1 /* 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.prism.sw; 27 28 import com.sun.prism.Image; 29 import com.sun.prism.PixelFormat; 30 import com.sun.prism.Texture; 31 import com.sun.prism.impl.PrismSettings; 32 33 abstract class SWTexture implements Texture { 34 35 static Texture create(SWResourceFactory factory, PixelFormat formatHint, WrapMode wrapMode, int w, int h) { 36 switch (formatHint) { 37 case BYTE_ALPHA: 38 return new SWMaskTexture(factory, wrapMode, w, h); 39 default: 40 return new SWArgbPreTexture(factory, wrapMode, w, h); 41 } 42 } 43 44 boolean allocated = false; 45 int physicalWidth, physicalHeight, contentWidth, contentHeight; 46 private SWResourceFactory factory; 47 private int lastImageSerial; 48 private final WrapMode wrapMode; 49 50 SWTexture(SWResourceFactory factory, WrapMode wrapMode, int w, int h) { 51 this.factory = factory; 52 this.wrapMode = wrapMode; 53 physicalWidth = w; 54 physicalHeight = h; 55 contentWidth = w; 56 contentHeight = h; 57 lock(); 58 } 59 60 SWTexture(SWTexture sharedTex, WrapMode altMode) { 61 this.allocated = sharedTex.allocated; 62 this.physicalWidth = sharedTex.physicalWidth; 63 this.physicalHeight = sharedTex.physicalHeight; 64 this.contentWidth = sharedTex.contentWidth; 65 this.contentHeight = sharedTex.contentHeight; 66 this.factory = sharedTex.factory; 67 // REMIND: Use indirection to share the serial number? 68 this.lastImageSerial = sharedTex.lastImageSerial; 69 this.wrapMode = altMode; 70 lock(); 71 } 72 73 SWResourceFactory getResourceFactory() { 74 return this.factory; 75 } 76 77 int getOffset() { 78 return 0; 79 } 80 81 private int lockcount; 82 public void lock() { 83 lockcount++; 84 } 85 86 public void unlock() { 87 assertLocked(); 88 lockcount--; 89 } 90 91 public boolean isLocked() { 92 return (lockcount > 0); 93 } 94 95 public int getLockCount() { 96 return lockcount; 97 } 98 99 public void assertLocked() { 100 if (lockcount <= 0) { 101 throw new IllegalStateException("texture not locked"); 102 } 103 } 104 105 boolean permanent; 106 public void makePermanent() { 107 permanent = true; 108 } 109 110 int employcount; 111 public void contentsUseful() { 112 assertLocked(); 113 employcount++; 114 } 115 116 public void contentsNotUseful() { 117 if (employcount <= 0) { 118 throw new IllegalStateException("Resource obsoleted too many times"); 119 } 120 employcount--; 121 } 122 123 public boolean isSurfaceLost() { 124 return false; 125 } 126 127 @Override 128 public void dispose() { } 129 130 @Override 131 public int getPhysicalWidth() { 132 return physicalWidth; 133 } 134 135 @Override 136 public int getPhysicalHeight() { 137 return physicalHeight; 138 } 139 140 @Override 141 public int getContentX() { 142 return 0; 143 } 144 145 @Override 146 public int getContentY() { 147 return 0; 148 } 149 150 @Override 151 public int getContentWidth() { 152 return contentWidth; 153 } 154 155 @Override 156 public void setContentWidth(int contentWidth) { 157 if (contentWidth > physicalWidth) { 158 throw new IllegalArgumentException("contentWidth cannot exceed physicalWidth"); 159 } 160 this.contentWidth = contentWidth; 161 } 162 163 @Override 164 public int getContentHeight() { 165 return contentHeight; 166 } 167 168 @Override 169 public void setContentHeight(int contentHeight) { 170 if (contentHeight > physicalHeight) { 171 throw new IllegalArgumentException("contentHeight cannot exceed physicalHeight"); 172 } 173 this.contentHeight = contentHeight; 174 } 175 176 @Override 177 public int getMaxContentWidth() { 178 return getPhysicalWidth(); 179 } 180 181 @Override 182 public int getMaxContentHeight() { 183 return getPhysicalHeight(); 184 } 185 186 public int getLastImageSerial() { 187 return lastImageSerial; 188 } 189 190 public void setLastImageSerial(int serial) { 191 lastImageSerial = serial; 192 } 193 194 @Override 195 public void update(Image img) { 196 this.update(img, 0, 0); 197 } 198 199 @Override 200 public void update(Image img, int dstx, int dsty) { 201 this.update(img, dstx, dsty, img.getWidth(), img.getHeight()); 202 } 203 204 @Override 205 public void update(Image img, int dstx, int dsty, int srcw, int srch) { 206 this.update(img, dstx, dsty, srcw, srch, false); 207 } 208 209 @Override 210 public void update(Image img, int dstx, int dsty, int srcw, int srch, boolean skipFlush) { 211 if (PrismSettings.debug) { 212 System.out.println("IMG.Bytes per pixel: " + img.getBytesPerPixelUnit()); 213 System.out.println("IMG.scanline: " + img.getScanlineStride()); 214 } 215 this.update(img.getPixelBuffer(), img.getPixelFormat(), dstx, dsty, 216 img.getMinX(), img.getMinY(), srcw, srch, img.getScanlineStride(), skipFlush); 217 } 218 219 @Override 220 public WrapMode getWrapMode() { 221 return wrapMode; 222 } 223 224 @Override 225 public boolean getUseMipmap() { 226 // TODO: Currently mipmapping not support for software texture 227 return false; 228 } 229 230 public Texture getSharedTexture(WrapMode altMode) { 231 assertLocked(); 232 if (wrapMode == altMode) { 233 lock(); 234 return this; 235 } 236 switch (altMode) { 237 case REPEAT: 238 if (wrapMode != WrapMode.CLAMP_TO_EDGE) { 239 return null; 240 } 241 break; 242 case CLAMP_TO_EDGE: 243 if (wrapMode != WrapMode.REPEAT) { 244 return null; 245 } 246 break; 247 default: 248 return null; 249 } 250 return this.createSharedLockedTexture(altMode); 251 } 252 253 @Override 254 public boolean getLinearFiltering() { 255 return false; 256 } 257 258 @Override 259 public void setLinearFiltering(boolean linear) { } 260 261 void allocate() { 262 if (allocated) { 263 return; 264 } 265 if (PrismSettings.debug) { 266 System.out.println("PCS Texture allocating buffer: " + this + ", " + physicalWidth + "x" + physicalHeight); 267 } 268 this.allocateBuffer(); 269 allocated = true; 270 } 271 272 abstract void allocateBuffer(); 273 274 /** 275 * Returns a new {@code Texture} object sharing all of the information 276 * from this texture, but using the new {@code WrapMode}. 277 * The new texture will be locked (in contrast to the similarly-named 278 * method in BaseTexture). 279 * 280 * @param altMode the new {@code WrapMode} for the new texture 281 * @return a new, locked, texture object sharing all information with 282 * this texture except for the {@code WrapMode} 283 */ 284 abstract Texture createSharedLockedTexture(WrapMode altMode); 285 }