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 17 package android.view; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Matrix; 21 22 import java.util.ArrayList; 23 24 /** 25 * An implementation of display list for OpenGL ES 2.0. 26 */ 27 class 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(int width, int height) { 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 70 mCanvas.setViewport(width, height); 71 // The dirty rect should always be null for a display list 72 mCanvas.onPreDraw(null); 73 74 return mCanvas; 75 } 76 @Override 77 public void clear() { 78 clearDirty(); 79 80 if (mCanvas != null) { 81 mCanvas.recycle(); 82 mCanvas = null; 83 } 84 mValid = false; 85 86 mBitmaps.clear(); 87 mChildDisplayLists.clear(); 88 } 89 90 @Override 91 public void reset() { 92 if (hasNativeDisplayList()) { 93 nReset(mFinalizer.mNativeDisplayList); 94 } 95 } 96 97 @Override 98 public boolean isValid() { 99 return mValid; 100 } 101 102 @Override 103 public void end() { 104 if (mCanvas != null) { 105 mCanvas.onPostDraw(); 106 if (mFinalizer != null) { 107 mCanvas.end(mFinalizer.mNativeDisplayList); 108 } else { 109 mFinalizer = new DisplayListFinalizer(mCanvas.end(0)); 110 nSetDisplayListName(mFinalizer.mNativeDisplayList, mName); 111 } 112 mCanvas.recycle(); 113 mCanvas = null; 114 mValid = true; 115 } 116 } 117 118 @Override 119 public int getSize() { 120 if (mFinalizer == null) return 0; 121 return nGetDisplayListSize(mFinalizer.mNativeDisplayList); 122 } 123 124 private static native void nDestroyDisplayList(int displayList); 125 private static native int nGetDisplayListSize(int displayList); 126 private static native void nSetDisplayListName(int displayList, String name); 127 128 /////////////////////////////////////////////////////////////////////////// 129 // Native View Properties 130 /////////////////////////////////////////////////////////////////////////// 131 132 @Override 133 public void setCaching(boolean caching) { 134 if (hasNativeDisplayList()) { 135 nSetCaching(mFinalizer.mNativeDisplayList, caching); 136 } 137 } 138 139 @Override 140 public void setClipToBounds(boolean clipToBounds) { 141 if (hasNativeDisplayList()) { 142 nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds); 143 } 144 } 145 146 @Override 147 public void setMatrix(Matrix matrix) { 148 if (hasNativeDisplayList()) { 149 nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance); 150 } 151 } 152 153 @Override 154 public Matrix getMatrix(Matrix matrix) { 155 if (hasNativeDisplayList()) { 156 nGetMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance); 157 } 158 return matrix; 159 } 160 161 @Override 162 public void setAnimationMatrix(Matrix matrix) { 163 if (hasNativeDisplayList()) { 164 nSetAnimationMatrix(mFinalizer.mNativeDisplayList, 165 (matrix != null) ? matrix.native_instance : 0); 166 } 167 } 168 169 @Override 170 public void setAlpha(float alpha) { 171 if (hasNativeDisplayList()) { 172 nSetAlpha(mFinalizer.mNativeDisplayList, alpha); 173 } 174 } 175 176 @Override 177 public float getAlpha() { 178 if (hasNativeDisplayList()) { 179 return nGetAlpha(mFinalizer.mNativeDisplayList); 180 } 181 return 1.0f; 182 } 183 184 @Override 185 public void setHasOverlappingRendering(boolean hasOverlappingRendering) { 186 if (hasNativeDisplayList()) { 187 nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering); 188 } 189 } 190 191 @Override 192 public boolean hasOverlappingRendering() { 193 //noinspection SimplifiableIfStatement 194 if (hasNativeDisplayList()) { 195 return nHasOverlappingRendering(mFinalizer.mNativeDisplayList); 196 } 197 return true; 198 } 199 200 @Override 201 public void setTranslationX(float translationX) { 202 if (hasNativeDisplayList()) { 203 nSetTranslationX(mFinalizer.mNativeDisplayList, translationX); 204 } 205 } 206 207 @Override 208 public float getTranslationX() { 209 if (hasNativeDisplayList()) { 210 return nGetTranslationX(mFinalizer.mNativeDisplayList); 211 } 212 return 0.0f; 213 } 214 215 @Override 216 public void setTranslationY(float translationY) { 217 if (hasNativeDisplayList()) { 218 nSetTranslationY(mFinalizer.mNativeDisplayList, translationY); 219 } 220 } 221 222 @Override 223 public float getTranslationY() { 224 if (hasNativeDisplayList()) { 225 return nGetTranslationY(mFinalizer.mNativeDisplayList); 226 } 227 return 0.0f; 228 } 229 230 @Override 231 public void setRotation(float rotation) { 232 if (hasNativeDisplayList()) { 233 nSetRotation(mFinalizer.mNativeDisplayList, rotation); 234 } 235 } 236 237 @Override 238 public float getRotation() { 239 if (hasNativeDisplayList()) { 240 return nGetRotation(mFinalizer.mNativeDisplayList); 241 } 242 return 0.0f; 243 } 244 245 @Override 246 public void setRotationX(float rotationX) { 247 if (hasNativeDisplayList()) { 248 nSetRotationX(mFinalizer.mNativeDisplayList, rotationX); 249 } 250 } 251 252 @Override 253 public float getRotationX() { 254 if (hasNativeDisplayList()) { 255 return nGetRotationX(mFinalizer.mNativeDisplayList); 256 } 257 return 0.0f; 258 } 259 260 @Override 261 public void setRotationY(float rotationY) { 262 if (hasNativeDisplayList()) { 263 nSetRotationY(mFinalizer.mNativeDisplayList, rotationY); 264 } 265 } 266 267 @Override 268 public float getRotationY() { 269 if (hasNativeDisplayList()) { 270 return nGetRotationY(mFinalizer.mNativeDisplayList); 271 } 272 return 0.0f; 273 } 274 275 @Override 276 public void setScaleX(float scaleX) { 277 if (hasNativeDisplayList()) { 278 nSetScaleX(mFinalizer.mNativeDisplayList, scaleX); 279 } 280 } 281 282 @Override 283 public float getScaleX() { 284 if (hasNativeDisplayList()) { 285 return nGetScaleX(mFinalizer.mNativeDisplayList); 286 } 287 return 1.0f; 288 } 289 290 @Override 291 public void setScaleY(float scaleY) { 292 if (hasNativeDisplayList()) { 293 nSetScaleY(mFinalizer.mNativeDisplayList, scaleY); 294 } 295 } 296 297 @Override 298 public float getScaleY() { 299 if (hasNativeDisplayList()) { 300 return nGetScaleY(mFinalizer.mNativeDisplayList); 301 } 302 return 1.0f; 303 } 304 305 @Override 306 public void setTransformationInfo(float alpha, float translationX, float translationY, 307 float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { 308 if (hasNativeDisplayList()) { 309 nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, translationX, translationY, 310 rotation, rotationX, rotationY, scaleX, scaleY); 311 } 312 } 313 314 @Override 315 public void setPivotX(float pivotX) { 316 if (hasNativeDisplayList()) { 317 nSetPivotX(mFinalizer.mNativeDisplayList, pivotX); 318 } 319 } 320 321 @Override 322 public float getPivotX() { 323 if (hasNativeDisplayList()) { 324 return nGetPivotX(mFinalizer.mNativeDisplayList); 325 } 326 return 0.0f; 327 } 328 329 @Override 330 public void setPivotY(float pivotY) { 331 if (hasNativeDisplayList()) { 332 nSetPivotY(mFinalizer.mNativeDisplayList, pivotY); 333 } 334 } 335 336 @Override 337 public float getPivotY() { 338 if (hasNativeDisplayList()) { 339 return nGetPivotY(mFinalizer.mNativeDisplayList); 340 } 341 return 0.0f; 342 } 343 344 @Override 345 public void setCameraDistance(float distance) { 346 if (hasNativeDisplayList()) { 347 nSetCameraDistance(mFinalizer.mNativeDisplayList, distance); 348 } 349 } 350 351 @Override 352 public float getCameraDistance() { 353 if (hasNativeDisplayList()) { 354 return nGetCameraDistance(mFinalizer.mNativeDisplayList); 355 } 356 return 0.0f; 357 } 358 359 @Override 360 public void setLeft(int left) { 361 if (hasNativeDisplayList()) { 362 nSetLeft(mFinalizer.mNativeDisplayList, left); 363 } 364 } 365 366 @Override 367 public float getLeft() { 368 if (hasNativeDisplayList()) { 369 return nGetLeft(mFinalizer.mNativeDisplayList); 370 } 371 return 0.0f; 372 } 373 374 @Override 375 public void setTop(int top) { 376 if (hasNativeDisplayList()) { 377 nSetTop(mFinalizer.mNativeDisplayList, top); 378 } 379 } 380 381 @Override 382 public float getTop() { 383 if (hasNativeDisplayList()) { 384 return nGetTop(mFinalizer.mNativeDisplayList); 385 } 386 return 0.0f; 387 } 388 389 @Override 390 public void setRight(int right) { 391 if (hasNativeDisplayList()) { 392 nSetRight(mFinalizer.mNativeDisplayList, right); 393 } 394 } 395 396 @Override 397 public float getRight() { 398 if (hasNativeDisplayList()) { 399 return nGetRight(mFinalizer.mNativeDisplayList); 400 } 401 return 0.0f; 402 } 403 404 @Override 405 public void setBottom(int bottom) { 406 if (hasNativeDisplayList()) { 407 nSetBottom(mFinalizer.mNativeDisplayList, bottom); 408 } 409 } 410 411 @Override 412 public float getBottom() { 413 if (hasNativeDisplayList()) { 414 return nGetBottom(mFinalizer.mNativeDisplayList); 415 } 416 return 0.0f; 417 } 418 419 @Override 420 public void setLeftTopRightBottom(int left, int top, int right, int bottom) { 421 if (hasNativeDisplayList()) { 422 nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom); 423 } 424 } 425 426 @Override 427 public void offsetLeftAndRight(float offset) { 428 if (hasNativeDisplayList()) { 429 nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset); 430 } 431 } 432 433 @Override 434 public void offsetTopAndBottom(float offset) { 435 if (hasNativeDisplayList()) { 436 nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset); 437 } 438 } 439 440 private static native void nReset(int displayList); 441 private static native void nOffsetTopAndBottom(int displayList, float offset); 442 private static native void nOffsetLeftAndRight(int displayList, float offset); 443 private static native void nSetLeftTopRightBottom(int displayList, int left, int top, 444 int right, int bottom); 445 private static native void nSetBottom(int displayList, int bottom); 446 private static native void nSetRight(int displayList, int right); 447 private static native void nSetTop(int displayList, int top); 448 private static native void nSetLeft(int displayList, int left); 449 private static native void nSetCameraDistance(int displayList, float distance); 450 private static native void nSetPivotY(int displayList, float pivotY); 451 private static native void nSetPivotX(int displayList, float pivotX); 452 private static native void nSetCaching(int displayList, boolean caching); 453 private static native void nSetClipToBounds(int displayList, boolean clipToBounds); 454 private static native void nSetAlpha(int displayList, float alpha); 455 private static native void nSetHasOverlappingRendering(int displayList, 456 boolean hasOverlappingRendering); 457 private static native void nSetTranslationX(int displayList, float translationX); 458 private static native void nSetTranslationY(int displayList, float translationY); 459 private static native void nSetRotation(int displayList, float rotation); 460 private static native void nSetRotationX(int displayList, float rotationX); 461 private static native void nSetRotationY(int displayList, float rotationY); 462 private static native void nSetScaleX(int displayList, float scaleX); 463 private static native void nSetScaleY(int displayList, float scaleY); 464 private static native void nSetTransformationInfo(int displayList, float alpha, 465 float translationX, float translationY, float rotation, float rotationX, 466 float rotationY, float scaleX, float scaleY); 467 private static native void nSetStaticMatrix(int displayList, int nativeMatrix); 468 private static native void nSetAnimationMatrix(int displayList, int animationMatrix); 469 470 private static native boolean nHasOverlappingRendering(int displayList); 471 private static native void nGetMatrix(int displayList, int matrix); 472 private static native float nGetAlpha(int displayList); 473 private static native float nGetLeft(int displayList); 474 private static native float nGetTop(int displayList); 475 private static native float nGetRight(int displayList); 476 private static native float nGetBottom(int displayList); 477 private static native float nGetCameraDistance(int displayList); 478 private static native float nGetScaleX(int displayList); 479 private static native float nGetScaleY(int displayList); 480 private static native float nGetTranslationX(int displayList); 481 private static native float nGetTranslationY(int displayList); 482 private static native float nGetRotation(int displayList); 483 private static native float nGetRotationX(int displayList); 484 private static native float nGetRotationY(int displayList); 485 private static native float nGetPivotX(int displayList); 486 private static native float nGetPivotY(int displayList); 487 488 /////////////////////////////////////////////////////////////////////////// 489 // Finalization 490 /////////////////////////////////////////////////////////////////////////// 491 492 private static class DisplayListFinalizer { 493 final int mNativeDisplayList; 494 495 public DisplayListFinalizer(int nativeDisplayList) { 496 mNativeDisplayList = nativeDisplayList; 497 } 498 499 @Override 500 protected void finalize() throws Throwable { 501 try { 502 nDestroyDisplayList(mNativeDisplayList); 503 } finally { 504 super.finalize(); 505 } 506 } 507 } 508 } 509