1 /* 2 * Copyright (c) 2011, 2018, 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 private boolean linearFiltering = true; 50 51 SWTexture(SWResourceFactory factory, WrapMode wrapMode, int w, int h) { 52 this.factory = factory; 53 this.wrapMode = wrapMode; 54 physicalWidth = w; 55 physicalHeight = h; 56 contentWidth = w; 57 contentHeight = h; 58 lock(); 59 } 60 61 SWTexture(SWTexture sharedTex, WrapMode altMode) { 62 this.allocated = sharedTex.allocated; 63 this.physicalWidth = sharedTex.physicalWidth; 64 this.physicalHeight = sharedTex.physicalHeight; 65 this.contentWidth = sharedTex.contentWidth; 66 this.contentHeight = sharedTex.contentHeight; 67 this.factory = sharedTex.factory; 68 // REMIND: Use indirection to share the serial number? 69 this.lastImageSerial = sharedTex.lastImageSerial; 70 this.linearFiltering = sharedTex.linearFiltering; 71 this.wrapMode = altMode; 72 lock(); 73 } 74 75 SWResourceFactory getResourceFactory() { 76 return this.factory; 77 } 78 79 int getOffset() { 80 return 0; 81 } 82 83 private int lockcount; 84 public void lock() { 85 lockcount++; 86 } 87 88 public void unlock() { 89 assertLocked(); 90 lockcount--; 91 } 92 93 public boolean isLocked() { 94 return (lockcount > 0); 95 } 96 97 public int getLockCount() { 98 return lockcount; 99 } 100 101 public void assertLocked() { 102 if (lockcount <= 0) { 103 throw new IllegalStateException("texture not locked"); 104 } 105 } 106 107 boolean permanent; 108 public void makePermanent() { 109 permanent = true; 110 } 111 112 int employcount; 113 public void contentsUseful() { 114 assertLocked(); 115 employcount++; 116 } 117 118 public void contentsNotUseful() { 119 if (employcount <= 0) { 120 throw new IllegalStateException("Resource obsoleted too many times"); 121 } 122 employcount--; 123 } 124 125 public boolean isSurfaceLost() { 126 return false; 127 } 128 129 @Override 130 public void dispose() { } 131 132 @Override 133 public int getPhysicalWidth() { 134 return physicalWidth; 135 } 136 137 @Override 138 public int getPhysicalHeight() { 139 return physicalHeight; 140 } 141 142 @Override 143 public int getContentX() { 144 return 0; 145 } 146 147 @Override 148 public int getContentY() { 149 return 0; 150 } 151 152 @Override 153 public int getContentWidth() { 154 return contentWidth; 155 } 156 157 @Override 158 public void setContentWidth(int contentWidth) { 159 if (contentWidth > physicalWidth) { 160 throw new IllegalArgumentException("contentWidth cannot exceed physicalWidth"); 161 } 162 this.contentWidth = contentWidth; 163 } 164 165 @Override 166 public int getContentHeight() { 167 return contentHeight; 168 } 169 170 @Override 171 public void setContentHeight(int contentHeight) { 172 if (contentHeight > physicalHeight) { 173 throw new IllegalArgumentException("contentHeight cannot exceed physicalHeight"); 174 } 175 this.contentHeight = contentHeight; 176 } 177 178 @Override 179 public int getMaxContentWidth() { 180 return getPhysicalWidth(); 181 } 182 183 @Override 184 public int getMaxContentHeight() { 185 return getPhysicalHeight(); 186 } 187 188 public int getLastImageSerial() { 189 return lastImageSerial; 190 } 191 192 public void setLastImageSerial(int serial) { 193 lastImageSerial = serial; 194 } 195 196 @Override 197 public void update(Image img) { 198 this.update(img, 0, 0); 199 } 200 201 @Override 202 public void update(Image img, int dstx, int dsty) { 203 this.update(img, dstx, dsty, img.getWidth(), img.getHeight()); 204 } 205 206 @Override 207 public void update(Image img, int dstx, int dsty, int srcw, int srch) { 208 this.update(img, dstx, dsty, srcw, srch, false); 209 } 210 211 @Override 212 public void update(Image img, int dstx, int dsty, int srcw, int srch, boolean skipFlush) { 213 if (PrismSettings.debug) { 214 System.out.println("IMG.Bytes per pixel: " + img.getBytesPerPixelUnit()); 215 System.out.println("IMG.scanline: " + img.getScanlineStride()); 216 } 217 this.update(img.getPixelBuffer(), img.getPixelFormat(), dstx, dsty, 218 img.getMinX(), img.getMinY(), srcw, srch, img.getScanlineStride(), skipFlush); 219 } 220 221 @Override 222 public WrapMode getWrapMode() { 223 return wrapMode; 224 } 225 226 @Override 227 public boolean getUseMipmap() { 228 // TODO: Currently mipmapping not support for software texture 229 return false; 230 } 231 232 public Texture getSharedTexture(WrapMode altMode) { 233 assertLocked(); 234 if (wrapMode == altMode) { 235 lock(); 236 return this; 237 } 238 switch (altMode) { 239 case REPEAT: 240 if (wrapMode != WrapMode.CLAMP_TO_EDGE) { 241 return null; 242 } 243 break; 244 case CLAMP_TO_EDGE: 245 if (wrapMode != WrapMode.REPEAT) { 246 return null; 247 } 248 break; 249 default: 250 return null; 251 } 252 return this.createSharedLockedTexture(altMode); 253 } 254 255 @Override 256 public boolean getLinearFiltering() { 257 return linearFiltering; 258 } 259 260 @Override 261 public void setLinearFiltering(boolean linear) { 262 linearFiltering = linear; 263 } 264 265 void allocate() { 266 if (allocated) { 267 return; 268 } 269 if (PrismSettings.debug) { 270 System.out.println("PCS Texture allocating buffer: " + this + ", " + physicalWidth + "x" + physicalHeight); 271 } 272 this.allocateBuffer(); 273 allocated = true; 274 } 275 276 abstract void allocateBuffer(); 277 278 /** 279 * Returns a new {@code Texture} object sharing all of the information 280 * from this texture, but using the new {@code WrapMode}. 281 * The new texture will be locked (in contrast to the similarly-named 282 * method in BaseTexture). 283 * 284 * @param altMode the new {@code WrapMode} for the new texture 285 * @return a new, locked, texture object sharing all information with 286 * this texture except for the {@code WrapMode} 287 */ 288 abstract Texture createSharedLockedTexture(WrapMode altMode); 289 }