Home | History | Annotate | Download | only in view
      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