1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.view; 18 19import android.graphics.Bitmap; 20import android.graphics.Matrix; 21 22import java.util.ArrayList; 23 24/** 25 * An implementation of display list for OpenGL ES 2.0. 26 */ 27class GLES20DisplayList extends DisplayList { 28 // These lists ensure that any Bitmaps and DisplayLists recorded by a DisplayList are kept 29 // alive as long as the DisplayList is alive. The Bitmap and DisplayList lists 30 // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are 31 // cleared at the start of a new drawing frame or when the view is detached from the window. 32 final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5); 33 final ArrayList<DisplayList> mChildDisplayLists = new ArrayList<DisplayList>(); 34 35 private GLES20RecordingCanvas mCanvas; 36 private boolean mValid; 37 38 // Used for debugging 39 private final String mName; 40 41 // The native display list will be destroyed when this object dies. 42 // DO NOT overwrite this reference once it is set. 43 private DisplayListFinalizer mFinalizer; 44 45 GLES20DisplayList(String name) { 46 mName = name; 47 } 48 49 boolean hasNativeDisplayList() { 50 return mValid && mFinalizer != null; 51 } 52 53 int getNativeDisplayList() { 54 if (!mValid || mFinalizer == null) { 55 throw new IllegalStateException("The display list is not valid."); 56 } 57 return mFinalizer.mNativeDisplayList; 58 } 59 60 @Override 61 public HardwareCanvas start() { 62 if (mCanvas != null) { 63 throw new IllegalStateException("Recording has already started"); 64 } 65 66 mValid = false; 67 mCanvas = GLES20RecordingCanvas.obtain(this); 68 mCanvas.start(); 69 return mCanvas; 70 } 71 72 @Override 73 public void invalidate() { 74 if (mCanvas != null) { 75 mCanvas.recycle(); 76 mCanvas = null; 77 } 78 mValid = false; 79 } 80 81 @Override 82 public void clear() { 83 if (!mValid) { 84 mBitmaps.clear(); 85 mChildDisplayLists.clear(); 86 } 87 } 88 89 @Override 90 public void reset() { 91 if (hasNativeDisplayList()) { 92 nReset(mFinalizer.mNativeDisplayList); 93 } 94 } 95 96 @Override 97 public boolean isValid() { 98 return mValid; 99 } 100 101 @Override 102 public void end() { 103 if (mCanvas != null) { 104 if (mFinalizer != null) { 105 mCanvas.end(mFinalizer.mNativeDisplayList); 106 } else { 107 mFinalizer = new DisplayListFinalizer(mCanvas.end(0)); 108 GLES20Canvas.setDisplayListName(mFinalizer.mNativeDisplayList, mName); 109 } 110 mCanvas.recycle(); 111 mCanvas = null; 112 mValid = true; 113 } 114 } 115 116 @Override 117 public int getSize() { 118 if (mFinalizer == null) return 0; 119 return GLES20Canvas.getDisplayListSize(mFinalizer.mNativeDisplayList); 120 } 121 122 /////////////////////////////////////////////////////////////////////////// 123 // Native View Properties 124 /////////////////////////////////////////////////////////////////////////// 125 126 @Override 127 public void setCaching(boolean caching) { 128 if (hasNativeDisplayList()) { 129 nSetCaching(mFinalizer.mNativeDisplayList, caching); 130 } 131 } 132 133 @Override 134 public void setClipChildren(boolean clipChildren) { 135 if (hasNativeDisplayList()) { 136 nSetClipChildren(mFinalizer.mNativeDisplayList, clipChildren); 137 } 138 } 139 140 @Override 141 public void setStaticMatrix(Matrix matrix) { 142 if (hasNativeDisplayList()) { 143 nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance); 144 } 145 } 146 147 @Override 148 public void setAnimationMatrix(Matrix matrix) { 149 if (hasNativeDisplayList()) { 150 nSetAnimationMatrix(mFinalizer.mNativeDisplayList, 151 (matrix != null) ? matrix.native_instance : 0); 152 } 153 } 154 155 @Override 156 public void setAlpha(float alpha) { 157 if (hasNativeDisplayList()) { 158 nSetAlpha(mFinalizer.mNativeDisplayList, alpha); 159 } 160 } 161 162 @Override 163 public void setHasOverlappingRendering(boolean hasOverlappingRendering) { 164 if (hasNativeDisplayList()) { 165 nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering); 166 } 167 } 168 169 @Override 170 public void setTranslationX(float translationX) { 171 if (hasNativeDisplayList()) { 172 nSetTranslationX(mFinalizer.mNativeDisplayList, translationX); 173 } 174 } 175 176 @Override 177 public void setTranslationY(float translationY) { 178 if (hasNativeDisplayList()) { 179 nSetTranslationY(mFinalizer.mNativeDisplayList, translationY); 180 } 181 } 182 183 @Override 184 public void setRotation(float rotation) { 185 if (hasNativeDisplayList()) { 186 nSetRotation(mFinalizer.mNativeDisplayList, rotation); 187 } 188 } 189 190 @Override 191 public void setRotationX(float rotationX) { 192 if (hasNativeDisplayList()) { 193 nSetRotationX(mFinalizer.mNativeDisplayList, rotationX); 194 } 195 } 196 197 @Override 198 public void setRotationY(float rotationY) { 199 if (hasNativeDisplayList()) { 200 nSetRotationY(mFinalizer.mNativeDisplayList, rotationY); 201 } 202 } 203 204 @Override 205 public void setScaleX(float scaleX) { 206 if (hasNativeDisplayList()) { 207 nSetScaleX(mFinalizer.mNativeDisplayList, scaleX); 208 } 209 } 210 211 @Override 212 public void setScaleY(float scaleY) { 213 if (hasNativeDisplayList()) { 214 nSetScaleY(mFinalizer.mNativeDisplayList, scaleY); 215 } 216 } 217 218 @Override 219 public void setTransformationInfo(float alpha, float translationX, float translationY, 220 float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { 221 if (hasNativeDisplayList()) { 222 nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, translationX, translationY, 223 rotation, rotationX, rotationY, scaleX, scaleY); 224 } 225 } 226 227 @Override 228 public void setPivotX(float pivotX) { 229 if (hasNativeDisplayList()) { 230 nSetPivotX(mFinalizer.mNativeDisplayList, pivotX); 231 } 232 } 233 234 @Override 235 public void setPivotY(float pivotY) { 236 if (hasNativeDisplayList()) { 237 nSetPivotY(mFinalizer.mNativeDisplayList, pivotY); 238 } 239 } 240 241 @Override 242 public void setCameraDistance(float distance) { 243 if (hasNativeDisplayList()) { 244 nSetCameraDistance(mFinalizer.mNativeDisplayList, distance); 245 } 246 } 247 248 @Override 249 public void setLeft(int left) { 250 if (hasNativeDisplayList()) { 251 nSetLeft(mFinalizer.mNativeDisplayList, left); 252 } 253 } 254 255 @Override 256 public void setTop(int top) { 257 if (hasNativeDisplayList()) { 258 nSetTop(mFinalizer.mNativeDisplayList, top); 259 } 260 } 261 262 @Override 263 public void setRight(int right) { 264 if (hasNativeDisplayList()) { 265 nSetRight(mFinalizer.mNativeDisplayList, right); 266 } 267 } 268 269 @Override 270 public void setBottom(int bottom) { 271 if (hasNativeDisplayList()) { 272 nSetBottom(mFinalizer.mNativeDisplayList, bottom); 273 } 274 } 275 276 @Override 277 public void setLeftTop(int left, int top) { 278 if (hasNativeDisplayList()) { 279 nSetLeftTop(mFinalizer.mNativeDisplayList, left, top); 280 } 281 } 282 283 @Override 284 public void setLeftTopRightBottom(int left, int top, int right, int bottom) { 285 if (hasNativeDisplayList()) { 286 nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom); 287 } 288 } 289 290 @Override 291 public void offsetLeftRight(int offset) { 292 if (hasNativeDisplayList()) { 293 nOffsetLeftRight(mFinalizer.mNativeDisplayList, offset); 294 } 295 } 296 297 @Override 298 public void offsetTopBottom(int offset) { 299 if (hasNativeDisplayList()) { 300 nOffsetTopBottom(mFinalizer.mNativeDisplayList, offset); 301 } 302 } 303 304 private static native void nReset(int displayList); 305 private static native void nOffsetTopBottom(int displayList, int offset); 306 private static native void nOffsetLeftRight(int displayList, int offset); 307 private static native void nSetLeftTopRightBottom(int displayList, int left, int top, 308 int right, int bottom); 309 private static native void nSetLeftTop(int displayList, int left, int top); 310 private static native void nSetBottom(int displayList, int bottom); 311 private static native void nSetRight(int displayList, int right); 312 private static native void nSetTop(int displayList, int top); 313 private static native void nSetLeft(int displayList, int left); 314 private static native void nSetCameraDistance(int displayList, float distance); 315 private static native void nSetPivotY(int displayList, float pivotY); 316 private static native void nSetPivotX(int displayList, float pivotX); 317 private static native void nSetCaching(int displayList, boolean caching); 318 private static native void nSetClipChildren(int displayList, boolean clipChildren); 319 private static native void nSetAlpha(int displayList, float alpha); 320 private static native void nSetHasOverlappingRendering(int displayList, 321 boolean hasOverlappingRendering); 322 private static native void nSetTranslationX(int displayList, float translationX); 323 private static native void nSetTranslationY(int displayList, float translationY); 324 private static native void nSetRotation(int displayList, float rotation); 325 private static native void nSetRotationX(int displayList, float rotationX); 326 private static native void nSetRotationY(int displayList, float rotationY); 327 private static native void nSetScaleX(int displayList, float scaleX); 328 private static native void nSetScaleY(int displayList, float scaleY); 329 private static native void nSetTransformationInfo(int displayList, float alpha, 330 float translationX, float translationY, float rotation, float rotationX, 331 float rotationY, float scaleX, float scaleY); 332 private static native void nSetStaticMatrix(int displayList, int nativeMatrix); 333 private static native void nSetAnimationMatrix(int displayList, int animationMatrix); 334 335 336 /////////////////////////////////////////////////////////////////////////// 337 // Finalization 338 /////////////////////////////////////////////////////////////////////////// 339 340 private static class DisplayListFinalizer { 341 final int mNativeDisplayList; 342 343 public DisplayListFinalizer(int nativeDisplayList) { 344 mNativeDisplayList = nativeDisplayList; 345 } 346 347 @Override 348 protected void finalize() throws Throwable { 349 try { 350 GLES20Canvas.destroyDisplayList(mNativeDisplayList); 351 } finally { 352 super.finalize(); 353 } 354 } 355 } 356} 357