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.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