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