Home | History | Annotate | Download | only in hwui
      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 #define LOG_TAG "OpenGLRenderer"
     18 
     19 #include <SkCamera.h>
     20 
     21 #include <private/hwui/DrawGlInfo.h>
     22 
     23 #include "DisplayListLogBuffer.h"
     24 #include "DisplayListRenderer.h"
     25 #include "Caches.h"
     26 
     27 namespace android {
     28 namespace uirenderer {
     29 
     30 ///////////////////////////////////////////////////////////////////////////////
     31 // Display list
     32 ///////////////////////////////////////////////////////////////////////////////
     33 
     34 const char* DisplayList::OP_NAMES[] = {
     35     "Save",
     36     "Restore",
     37     "RestoreToCount",
     38     "SaveLayer",
     39     "SaveLayerAlpha",
     40     "Translate",
     41     "Rotate",
     42     "Scale",
     43     "Skew",
     44     "SetMatrix",
     45     "ConcatMatrix",
     46     "ClipRect",
     47     "DrawDisplayList",
     48     "DrawLayer",
     49     "DrawBitmap",
     50     "DrawBitmapMatrix",
     51     "DrawBitmapRect",
     52     "DrawBitmapData",
     53     "DrawBitmapMesh",
     54     "DrawPatch",
     55     "DrawColor",
     56     "DrawRect",
     57     "DrawRoundRect",
     58     "DrawCircle",
     59     "DrawOval",
     60     "DrawArc",
     61     "DrawPath",
     62     "DrawLines",
     63     "DrawPoints",
     64     "DrawText",
     65     "DrawTextOnPath",
     66     "DrawPosText",
     67     "ResetShader",
     68     "SetupShader",
     69     "ResetColorFilter",
     70     "SetupColorFilter",
     71     "ResetShadow",
     72     "SetupShadow",
     73     "ResetPaintFilter",
     74     "SetupPaintFilter",
     75     "DrawGLFunction"
     76 };
     77 
     78 void DisplayList::outputLogBuffer(int fd) {
     79     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     80     if (logBuffer.isEmpty()) {
     81         return;
     82     }
     83 
     84     FILE *file = fdopen(fd, "a");
     85 
     86     fprintf(file, "\nRecent DisplayList operations\n");
     87     logBuffer.outputCommands(file, OP_NAMES);
     88 
     89     String8 cachesLog;
     90     Caches::getInstance().dumpMemoryUsage(cachesLog);
     91     fprintf(file, "\nCaches:\n%s", cachesLog.string());
     92     fprintf(file, "\n");
     93 
     94     fflush(file);
     95 }
     96 
     97 DisplayList::DisplayList(const DisplayListRenderer& recorder) :
     98     mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
     99     mStaticMatrix(NULL), mAnimationMatrix(NULL) {
    100 
    101     initFromDisplayListRenderer(recorder);
    102 }
    103 
    104 DisplayList::~DisplayList() {
    105     clearResources();
    106 }
    107 
    108 void DisplayList::initProperties() {
    109     mLeft = 0;
    110     mTop = 0;
    111     mRight = 0;
    112     mBottom = 0;
    113     mClipChildren = true;
    114     mAlpha = 1;
    115     mMultipliedAlpha = 255;
    116     mHasOverlappingRendering = true;
    117     mTranslationX = 0;
    118     mTranslationY = 0;
    119     mRotation = 0;
    120     mRotationX = 0;
    121     mRotationY= 0;
    122     mScaleX = 1;
    123     mScaleY = 1;
    124     mPivotX = 0;
    125     mPivotY = 0;
    126     mCameraDistance = 0;
    127     mMatrixDirty = false;
    128     mMatrixFlags = 0;
    129     mPrevWidth = -1;
    130     mPrevHeight = -1;
    131     mWidth = 0;
    132     mHeight = 0;
    133     mPivotExplicitlySet = false;
    134     mCaching = false;
    135 }
    136 
    137 void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
    138     if (displayList) {
    139         DISPLAY_LIST_LOGD("Deferring display list destruction");
    140         Caches::getInstance().deleteDisplayListDeferred(displayList);
    141     }
    142 }
    143 
    144 void DisplayList::clearResources() {
    145     sk_free((void*) mReader.base());
    146 
    147     delete mTransformMatrix;
    148     delete mTransformCamera;
    149     delete mTransformMatrix3D;
    150     delete mStaticMatrix;
    151     delete mAnimationMatrix;
    152     mTransformMatrix = NULL;
    153     mTransformCamera = NULL;
    154     mTransformMatrix3D = NULL;
    155     mStaticMatrix = NULL;
    156     mAnimationMatrix = NULL;
    157 
    158     Caches& caches = Caches::getInstance();
    159 
    160     for (size_t i = 0; i < mBitmapResources.size(); i++) {
    161         caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
    162     }
    163     mBitmapResources.clear();
    164 
    165     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
    166         SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
    167         caches.resourceCache.decrementRefcount(bitmap);
    168         caches.resourceCache.destructor(bitmap);
    169     }
    170     mOwnedBitmapResources.clear();
    171 
    172     for (size_t i = 0; i < mFilterResources.size(); i++) {
    173         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
    174     }
    175     mFilterResources.clear();
    176 
    177     for (size_t i = 0; i < mShaders.size(); i++) {
    178         caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
    179         caches.resourceCache.destructor(mShaders.itemAt(i));
    180     }
    181     mShaders.clear();
    182 
    183     for (size_t i = 0; i < mPaints.size(); i++) {
    184         delete mPaints.itemAt(i);
    185     }
    186     mPaints.clear();
    187 
    188     for (size_t i = 0; i < mPaths.size(); i++) {
    189         SkPath* path = mPaths.itemAt(i);
    190         caches.pathCache.remove(path);
    191         delete path;
    192     }
    193     mPaths.clear();
    194 
    195     for (size_t i = 0; i < mSourcePaths.size(); i++) {
    196         caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
    197     }
    198     mSourcePaths.clear();
    199 
    200     for (size_t i = 0; i < mMatrices.size(); i++) {
    201         delete mMatrices.itemAt(i);
    202     }
    203     mMatrices.clear();
    204 }
    205 
    206 void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
    207     const SkWriter32& writer = recorder.writeStream();
    208     init();
    209 
    210     if (writer.size() == 0) {
    211         return;
    212     }
    213 
    214     if (reusing) {
    215         // re-using display list - clear out previous allocations
    216         clearResources();
    217     }
    218     initProperties();
    219 
    220     mSize = writer.size();
    221     void* buffer = sk_malloc_throw(mSize);
    222     writer.flatten(buffer);
    223     mReader.setMemory(buffer, mSize);
    224 
    225     Caches& caches = Caches::getInstance();
    226 
    227     const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
    228     for (size_t i = 0; i < bitmapResources.size(); i++) {
    229         SkBitmap* resource = bitmapResources.itemAt(i);
    230         mBitmapResources.add(resource);
    231         caches.resourceCache.incrementRefcount(resource);
    232     }
    233 
    234     const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
    235     for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
    236         SkBitmap* resource = ownedBitmapResources.itemAt(i);
    237         mOwnedBitmapResources.add(resource);
    238         caches.resourceCache.incrementRefcount(resource);
    239     }
    240 
    241     const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
    242     for (size_t i = 0; i < filterResources.size(); i++) {
    243         SkiaColorFilter* resource = filterResources.itemAt(i);
    244         mFilterResources.add(resource);
    245         caches.resourceCache.incrementRefcount(resource);
    246     }
    247 
    248     const Vector<SkiaShader*>& shaders = recorder.getShaders();
    249     for (size_t i = 0; i < shaders.size(); i++) {
    250         SkiaShader* resource = shaders.itemAt(i);
    251         mShaders.add(resource);
    252         caches.resourceCache.incrementRefcount(resource);
    253     }
    254 
    255     const Vector<SkPaint*>& paints = recorder.getPaints();
    256     for (size_t i = 0; i < paints.size(); i++) {
    257         mPaints.add(paints.itemAt(i));
    258     }
    259 
    260     const Vector<SkPath*>& paths = recorder.getPaths();
    261     for (size_t i = 0; i < paths.size(); i++) {
    262         mPaths.add(paths.itemAt(i));
    263     }
    264 
    265     const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
    266     for (size_t i = 0; i < sourcePaths.size(); i++) {
    267         mSourcePaths.add(sourcePaths.itemAt(i));
    268         caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
    269     }
    270 
    271     const Vector<SkMatrix*>& matrices = recorder.getMatrices();
    272     for (size_t i = 0; i < matrices.size(); i++) {
    273         mMatrices.add(matrices.itemAt(i));
    274     }
    275 }
    276 
    277 void DisplayList::init() {
    278     mSize = 0;
    279     mIsRenderable = true;
    280 }
    281 
    282 size_t DisplayList::getSize() {
    283     return mSize;
    284 }
    285 
    286 /**
    287  * This function is a simplified version of replay(), where we simply retrieve and log the
    288  * display list. This function should remain in sync with the replay() function.
    289  */
    290 void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
    291     TextContainer text;
    292 
    293     uint32_t count = (level + 1) * 2;
    294     char indent[count + 1];
    295     for (uint32_t i = 0; i < count; i++) {
    296         indent[i] = ' ';
    297     }
    298     indent[count] = '\0';
    299     ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this,
    300             mName.string(), isRenderable());
    301 
    302     ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
    303     int saveCount = renderer.getSaveCount() - 1;
    304 
    305     outputViewProperties(renderer, (char*) indent);
    306     mReader.rewind();
    307 
    308     while (!mReader.eof()) {
    309         int op = mReader.readInt();
    310         if (op & OP_MAY_BE_SKIPPED_MASK) {
    311             int skip = mReader.readInt();
    312             ALOGD("%sSkip %d", (char*) indent, skip);
    313             op &= ~OP_MAY_BE_SKIPPED_MASK;
    314         }
    315 
    316         switch (op) {
    317             case DrawGLFunction: {
    318                 Functor *functor = (Functor *) getInt();
    319                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
    320             }
    321             break;
    322             case Save: {
    323                 int rendererNum = getInt();
    324                 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
    325             }
    326             break;
    327             case Restore: {
    328                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    329             }
    330             break;
    331             case RestoreToCount: {
    332                 int restoreCount = saveCount + getInt();
    333                 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
    334             }
    335             break;
    336             case SaveLayer: {
    337                 float f1 = getFloat();
    338                 float f2 = getFloat();
    339                 float f3 = getFloat();
    340                 float f4 = getFloat();
    341                 SkPaint* paint = getPaint(renderer);
    342                 int flags = getInt();
    343                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
    344                         OP_NAMES[op], f1, f2, f3, f4, paint, flags);
    345             }
    346             break;
    347             case SaveLayerAlpha: {
    348                 float f1 = getFloat();
    349                 float f2 = getFloat();
    350                 float f3 = getFloat();
    351                 float f4 = getFloat();
    352                 int alpha = getInt();
    353                 int flags = getInt();
    354                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
    355                         OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
    356             }
    357             break;
    358             case Translate: {
    359                 float f1 = getFloat();
    360                 float f2 = getFloat();
    361                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
    362             }
    363             break;
    364             case Rotate: {
    365                 float rotation = getFloat();
    366                 ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
    367             }
    368             break;
    369             case Scale: {
    370                 float sx = getFloat();
    371                 float sy = getFloat();
    372                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
    373             }
    374             break;
    375             case Skew: {
    376                 float sx = getFloat();
    377                 float sy = getFloat();
    378                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
    379             }
    380             break;
    381             case SetMatrix: {
    382                 SkMatrix* matrix = getMatrix();
    383                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
    384             }
    385             break;
    386             case ConcatMatrix: {
    387                 SkMatrix* matrix = getMatrix();
    388                 ALOGD("%s%s new concat %p: [%f, %f, %f]   [%f, %f, %f]   [%f, %f, %f]",
    389                         (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
    390                         matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
    391                         matrix->get(6), matrix->get(7), matrix->get(8));
    392             }
    393             break;
    394             case ClipRect: {
    395                 float f1 = getFloat();
    396                 float f2 = getFloat();
    397                 float f3 = getFloat();
    398                 float f4 = getFloat();
    399                 int regionOp = getInt();
    400                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
    401                         f1, f2, f3, f4, regionOp);
    402             }
    403             break;
    404             case DrawDisplayList: {
    405                 DisplayList* displayList = getDisplayList();
    406                 int32_t flags = getInt();
    407                 ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
    408                         displayList, mWidth, mHeight, flags, level + 1);
    409                 renderer.outputDisplayList(displayList, level + 1);
    410             }
    411             break;
    412             case DrawLayer: {
    413                 Layer* layer = (Layer*) getInt();
    414                 float x = getFloat();
    415                 float y = getFloat();
    416                 SkPaint* paint = getPaint(renderer);
    417                 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
    418                         layer, x, y, paint);
    419             }
    420             break;
    421             case DrawBitmap: {
    422                 SkBitmap* bitmap = getBitmap();
    423                 float x = getFloat();
    424                 float y = getFloat();
    425                 SkPaint* paint = getPaint(renderer);
    426                 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
    427                         bitmap, x, y, paint);
    428             }
    429             break;
    430             case DrawBitmapMatrix: {
    431                 SkBitmap* bitmap = getBitmap();
    432                 SkMatrix* matrix = getMatrix();
    433                 SkPaint* paint = getPaint(renderer);
    434                 ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
    435                         bitmap, matrix, paint);
    436             }
    437             break;
    438             case DrawBitmapRect: {
    439                 SkBitmap* bitmap = getBitmap();
    440                 float f1 = getFloat();
    441                 float f2 = getFloat();
    442                 float f3 = getFloat();
    443                 float f4 = getFloat();
    444                 float f5 = getFloat();
    445                 float f6 = getFloat();
    446                 float f7 = getFloat();
    447                 float f8 = getFloat();
    448                 SkPaint* paint = getPaint(renderer);
    449                 ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
    450                         (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
    451             }
    452             break;
    453             case DrawBitmapData: {
    454                 SkBitmap* bitmap = getBitmapData();
    455                 float x = getFloat();
    456                 float y = getFloat();
    457                 SkPaint* paint = getPaint(renderer);
    458                 ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint);
    459             }
    460             break;
    461             case DrawBitmapMesh: {
    462                 int verticesCount = 0;
    463                 uint32_t colorsCount = 0;
    464                 SkBitmap* bitmap = getBitmap();
    465                 uint32_t meshWidth = getInt();
    466                 uint32_t meshHeight = getInt();
    467                 float* vertices = getFloats(verticesCount);
    468                 bool hasColors = getInt();
    469                 int* colors = hasColors ? getInts(colorsCount) : NULL;
    470                 SkPaint* paint = getPaint(renderer);
    471                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    472             }
    473             break;
    474             case DrawPatch: {
    475                 int32_t* xDivs = NULL;
    476                 int32_t* yDivs = NULL;
    477                 uint32_t* colors = NULL;
    478                 uint32_t xDivsCount = 0;
    479                 uint32_t yDivsCount = 0;
    480                 int8_t numColors = 0;
    481                 SkBitmap* bitmap = getBitmap();
    482                 xDivs = getInts(xDivsCount);
    483                 yDivs = getInts(yDivsCount);
    484                 colors = getUInts(numColors);
    485                 float left = getFloat();
    486                 float top = getFloat();
    487                 float right = getFloat();
    488                 float bottom = getFloat();
    489                 SkPaint* paint = getPaint(renderer);
    490                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
    491                         left, top, right, bottom);
    492             }
    493             break;
    494             case DrawColor: {
    495                 int color = getInt();
    496                 int xferMode = getInt();
    497                 ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
    498             }
    499             break;
    500             case DrawRect: {
    501                 float f1 = getFloat();
    502                 float f2 = getFloat();
    503                 float f3 = getFloat();
    504                 float f4 = getFloat();
    505                 SkPaint* paint = getPaint(renderer);
    506                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
    507                         f1, f2, f3, f4, paint);
    508             }
    509             break;
    510             case DrawRoundRect: {
    511                 float f1 = getFloat();
    512                 float f2 = getFloat();
    513                 float f3 = getFloat();
    514                 float f4 = getFloat();
    515                 float f5 = getFloat();
    516                 float f6 = getFloat();
    517                 SkPaint* paint = getPaint(renderer);
    518                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
    519                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
    520             }
    521             break;
    522             case DrawCircle: {
    523                 float f1 = getFloat();
    524                 float f2 = getFloat();
    525                 float f3 = getFloat();
    526                 SkPaint* paint = getPaint(renderer);
    527                 ALOGD("%s%s %.2f, %.2f, %.2f, %p",
    528                         (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
    529             }
    530             break;
    531             case DrawOval: {
    532                 float f1 = getFloat();
    533                 float f2 = getFloat();
    534                 float f3 = getFloat();
    535                 float f4 = getFloat();
    536                 SkPaint* paint = getPaint(renderer);
    537                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
    538                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
    539             }
    540             break;
    541             case DrawArc: {
    542                 float f1 = getFloat();
    543                 float f2 = getFloat();
    544                 float f3 = getFloat();
    545                 float f4 = getFloat();
    546                 float f5 = getFloat();
    547                 float f6 = getFloat();
    548                 int i1 = getInt();
    549                 SkPaint* paint = getPaint(renderer);
    550                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
    551                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
    552             }
    553             break;
    554             case DrawPath: {
    555                 SkPath* path = getPath();
    556                 SkPaint* paint = getPaint(renderer);
    557                 ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
    558             }
    559             break;
    560             case DrawLines: {
    561                 int count = 0;
    562                 float* points = getFloats(count);
    563                 SkPaint* paint = getPaint(renderer);
    564                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    565             }
    566             break;
    567             case DrawPoints: {
    568                 int count = 0;
    569                 float* points = getFloats(count);
    570                 SkPaint* paint = getPaint(renderer);
    571                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    572             }
    573             break;
    574             case DrawText: {
    575                 getText(&text);
    576                 int32_t count = getInt();
    577                 float x = getFloat();
    578                 float y = getFloat();
    579                 SkPaint* paint = getPaint(renderer);
    580                 float length = getFloat();
    581                 ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
    582                         text.text(), text.length(), count, x, y, paint, length);
    583             }
    584             break;
    585             case DrawTextOnPath: {
    586                 getText(&text);
    587                 int32_t count = getInt();
    588                 SkPath* path = getPath();
    589                 float hOffset = getFloat();
    590                 float vOffset = getFloat();
    591                 SkPaint* paint = getPaint(renderer);
    592                 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
    593                     text.text(), text.length(), count, paint);
    594             }
    595             break;
    596             case DrawPosText: {
    597                 getText(&text);
    598                 int count = getInt();
    599                 int positionsCount = 0;
    600                 float* positions = getFloats(positionsCount);
    601                 SkPaint* paint = getPaint(renderer);
    602                 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
    603                         text.text(), text.length(), count, paint);
    604             }
    605             case ResetShader: {
    606                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    607             }
    608             break;
    609             case SetupShader: {
    610                 SkiaShader* shader = getShader();
    611                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
    612             }
    613             break;
    614             case ResetColorFilter: {
    615                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    616             }
    617             break;
    618             case SetupColorFilter: {
    619                 SkiaColorFilter *colorFilter = getColorFilter();
    620                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
    621             }
    622             break;
    623             case ResetShadow: {
    624                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    625             }
    626             break;
    627             case SetupShadow: {
    628                 float radius = getFloat();
    629                 float dx = getFloat();
    630                 float dy = getFloat();
    631                 int color = getInt();
    632                 ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
    633                         radius, dx, dy, color);
    634             }
    635             break;
    636             case ResetPaintFilter: {
    637                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
    638             }
    639             break;
    640             case SetupPaintFilter: {
    641                 int clearBits = getInt();
    642                 int setBits = getInt();
    643                 ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
    644             }
    645             break;
    646             default:
    647                 ALOGD("Display List error: op not handled: %s%s",
    648                         (char*) indent, OP_NAMES[op]);
    649                 break;
    650         }
    651     }
    652     ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
    653 }
    654 
    655 void DisplayList::updateMatrix() {
    656     if (mMatrixDirty) {
    657         if (!mTransformMatrix) {
    658             mTransformMatrix = new SkMatrix();
    659         }
    660         if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
    661             mTransformMatrix->reset();
    662         } else {
    663             if (!mPivotExplicitlySet) {
    664                 if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
    665                     mPrevWidth = mWidth;
    666                     mPrevHeight = mHeight;
    667                     mPivotX = mPrevWidth / 2;
    668                     mPivotY = mPrevHeight / 2;
    669                 }
    670             }
    671             if ((mMatrixFlags & ROTATION_3D) == 0) {
    672                 mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
    673                 mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
    674                 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
    675             } else {
    676                 if (!mTransformCamera) {
    677                     mTransformCamera = new Sk3DView();
    678                     mTransformMatrix3D = new SkMatrix();
    679                 }
    680                 mTransformMatrix->reset();
    681                 mTransformCamera->save();
    682                 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
    683                 mTransformCamera->rotateX(mRotationX);
    684                 mTransformCamera->rotateY(mRotationY);
    685                 mTransformCamera->rotateZ(-mRotation);
    686                 mTransformCamera->getMatrix(mTransformMatrix3D);
    687                 mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
    688                 mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
    689                         mPivotY + mTranslationY);
    690                 mTransformMatrix->postConcat(*mTransformMatrix3D);
    691                 mTransformCamera->restore();
    692             }
    693         }
    694         mMatrixDirty = false;
    695     }
    696 }
    697 
    698 void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
    699     updateMatrix();
    700     if (mLeft != 0 || mTop != 0) {
    701         ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
    702     }
    703     if (mStaticMatrix) {
    704         ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    705                 indent, "ConcatMatrix (static)", mStaticMatrix,
    706                 mStaticMatrix->get(0), mStaticMatrix->get(1),
    707                 mStaticMatrix->get(2), mStaticMatrix->get(3),
    708                 mStaticMatrix->get(4), mStaticMatrix->get(5),
    709                 mStaticMatrix->get(6), mStaticMatrix->get(7),
    710                 mStaticMatrix->get(8));
    711     }
    712     if (mAnimationMatrix) {
    713         ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    714                 indent, "ConcatMatrix (animation)", mAnimationMatrix,
    715                 mAnimationMatrix->get(0), mAnimationMatrix->get(1),
    716                 mAnimationMatrix->get(2), mAnimationMatrix->get(3),
    717                 mAnimationMatrix->get(4), mAnimationMatrix->get(5),
    718                 mAnimationMatrix->get(6), mAnimationMatrix->get(7),
    719                 mAnimationMatrix->get(8));
    720     }
    721     if (mMatrixFlags != 0) {
    722         if (mMatrixFlags == TRANSLATION) {
    723             ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
    724         } else {
    725             ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    726                     indent, "ConcatMatrix", mTransformMatrix,
    727                     mTransformMatrix->get(0), mTransformMatrix->get(1),
    728                     mTransformMatrix->get(2), mTransformMatrix->get(3),
    729                     mTransformMatrix->get(4), mTransformMatrix->get(5),
    730                     mTransformMatrix->get(6), mTransformMatrix->get(7),
    731                     mTransformMatrix->get(8));
    732         }
    733     }
    734     if (mAlpha < 1 && !mCaching) {
    735         // TODO: should be able to store the size of a DL at record time and not
    736         // have to pass it into this call. In fact, this information might be in the
    737         // location/size info that we store with the new native transform data.
    738         int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
    739         if (mClipChildren) {
    740             flags |= SkCanvas::kClipToLayer_SaveFlag;
    741         }
    742         ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
    743                 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
    744                 mMultipliedAlpha, flags);
    745     }
    746     if (mClipChildren) {
    747         ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
    748                 (float) mRight - mLeft, (float) mBottom - mTop);
    749     }
    750 }
    751 
    752 void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
    753 #if DEBUG_DISPLAY_LIST
    754         uint32_t count = (level + 1) * 2;
    755         char indent[count + 1];
    756         for (uint32_t i = 0; i < count; i++) {
    757             indent[i] = ' ';
    758         }
    759         indent[count] = '\0';
    760 #endif
    761     updateMatrix();
    762     if (mLeft != 0 || mTop != 0) {
    763         DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
    764         renderer.translate(mLeft, mTop);
    765     }
    766     if (mStaticMatrix) {
    767         DISPLAY_LIST_LOGD(
    768                 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    769                 indent, "ConcatMatrix (static)", mStaticMatrix,
    770                 mStaticMatrix->get(0), mStaticMatrix->get(1),
    771                 mStaticMatrix->get(2), mStaticMatrix->get(3),
    772                 mStaticMatrix->get(4), mStaticMatrix->get(5),
    773                 mStaticMatrix->get(6), mStaticMatrix->get(7),
    774                 mStaticMatrix->get(8));
    775         renderer.concatMatrix(mStaticMatrix);
    776     } else if (mAnimationMatrix) {
    777         DISPLAY_LIST_LOGD(
    778                 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    779                 indent, "ConcatMatrix (animation)", mAnimationMatrix,
    780                 mAnimationMatrix->get(0), mAnimationMatrix->get(1),
    781                 mAnimationMatrix->get(2), mAnimationMatrix->get(3),
    782                 mAnimationMatrix->get(4), mAnimationMatrix->get(5),
    783                 mAnimationMatrix->get(6), mAnimationMatrix->get(7),
    784                 mAnimationMatrix->get(8));
    785         renderer.concatMatrix(mAnimationMatrix);
    786     }
    787     if (mMatrixFlags != 0) {
    788         if (mMatrixFlags == TRANSLATION) {
    789             DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
    790             renderer.translate(mTranslationX, mTranslationY);
    791         } else {
    792             DISPLAY_LIST_LOGD(
    793                     "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    794                     indent, "ConcatMatrix", mTransformMatrix,
    795                     mTransformMatrix->get(0), mTransformMatrix->get(1),
    796                     mTransformMatrix->get(2), mTransformMatrix->get(3),
    797                     mTransformMatrix->get(4), mTransformMatrix->get(5),
    798                     mTransformMatrix->get(6), mTransformMatrix->get(7),
    799                     mTransformMatrix->get(8));
    800             renderer.concatMatrix(mTransformMatrix);
    801         }
    802     }
    803     if (mAlpha < 1 && !mCaching) {
    804         if (!mHasOverlappingRendering) {
    805             DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
    806             renderer.setAlpha(mAlpha);
    807         } else {
    808             // TODO: should be able to store the size of a DL at record time and not
    809             // have to pass it into this call. In fact, this information might be in the
    810             // location/size info that we store with the new native transform data.
    811             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
    812             if (mClipChildren) {
    813                 flags |= SkCanvas::kClipToLayer_SaveFlag;
    814             }
    815             DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
    816                     (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
    817                     mMultipliedAlpha, flags);
    818             renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
    819                     mMultipliedAlpha, flags);
    820         }
    821     }
    822     if (mClipChildren) {
    823         DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
    824                 (float) mRight - mLeft, (float) mBottom - mTop);
    825         renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
    826                 SkRegion::kIntersect_Op);
    827     }
    828 }
    829 
    830 /**
    831  * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
    832  * in the output() function, since that function processes the same list of opcodes for the
    833  * purposes of logging display list info for a given view.
    834  */
    835 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
    836     status_t drawGlStatus = DrawGlInfo::kStatusDone;
    837     TextContainer text;
    838     mReader.rewind();
    839 
    840 #if DEBUG_DISPLAY_LIST
    841     uint32_t count = (level + 1) * 2;
    842     char indent[count + 1];
    843     for (uint32_t i = 0; i < count; i++) {
    844         indent[i] = ' ';
    845     }
    846     indent[count] = '\0';
    847     Rect* clipRect = renderer.getClipRect();
    848     DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
    849             (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
    850             clipRect->right, clipRect->bottom);
    851 #endif
    852 
    853     renderer.startMark(mName.string());
    854     int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
    855     DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
    856             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
    857     setViewProperties(renderer, level);
    858     if (renderer.quickReject(0, 0, mWidth, mHeight)) {
    859         DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
    860         renderer.restoreToCount(restoreTo);
    861         renderer.endMark();
    862         return drawGlStatus;
    863     }
    864 
    865     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
    866     int saveCount = renderer.getSaveCount() - 1;
    867     while (!mReader.eof()) {
    868         int op = mReader.readInt();
    869         if (op & OP_MAY_BE_SKIPPED_MASK) {
    870             int32_t skip = mReader.readInt();
    871             if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
    872                 mReader.skip(skip);
    873                 DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
    874                         OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
    875                 continue;
    876             } else {
    877                 op &= ~OP_MAY_BE_SKIPPED_MASK;
    878             }
    879         }
    880         logBuffer.writeCommand(level, op);
    881 
    882         switch (op) {
    883             case DrawGLFunction: {
    884                 Functor *functor = (Functor *) getInt();
    885                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
    886                 renderer.startMark("GL functor");
    887                 drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
    888                 renderer.endMark();
    889             }
    890             break;
    891             case Save: {
    892                 int32_t rendererNum = getInt();
    893                 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
    894                 renderer.save(rendererNum);
    895             }
    896             break;
    897             case Restore: {
    898                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
    899                 renderer.restore();
    900             }
    901             break;
    902             case RestoreToCount: {
    903                 int32_t restoreCount = saveCount + getInt();
    904                 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
    905                 renderer.restoreToCount(restoreCount);
    906             }
    907             break;
    908             case SaveLayer: {
    909                 float f1 = getFloat();
    910                 float f2 = getFloat();
    911                 float f3 = getFloat();
    912                 float f4 = getFloat();
    913                 SkPaint* paint = getPaint(renderer);
    914                 int32_t flags = getInt();
    915                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
    916                         OP_NAMES[op], f1, f2, f3, f4, paint, flags);
    917                 renderer.saveLayer(f1, f2, f3, f4, paint, flags);
    918             }
    919             break;
    920             case SaveLayerAlpha: {
    921                 float f1 = getFloat();
    922                 float f2 = getFloat();
    923                 float f3 = getFloat();
    924                 float f4 = getFloat();
    925                 int32_t alpha = getInt();
    926                 int32_t flags = getInt();
    927                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
    928                         OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
    929                 renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
    930             }
    931             break;
    932             case Translate: {
    933                 float f1 = getFloat();
    934                 float f2 = getFloat();
    935                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
    936                 renderer.translate(f1, f2);
    937             }
    938             break;
    939             case Rotate: {
    940                 float rotation = getFloat();
    941                 DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
    942                 renderer.rotate(rotation);
    943             }
    944             break;
    945             case Scale: {
    946                 float sx = getFloat();
    947                 float sy = getFloat();
    948                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
    949                 renderer.scale(sx, sy);
    950             }
    951             break;
    952             case Skew: {
    953                 float sx = getFloat();
    954                 float sy = getFloat();
    955                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
    956                 renderer.skew(sx, sy);
    957             }
    958             break;
    959             case SetMatrix: {
    960                 SkMatrix* matrix = getMatrix();
    961                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
    962                 renderer.setMatrix(matrix);
    963             }
    964             break;
    965             case ConcatMatrix: {
    966                 SkMatrix* matrix = getMatrix();
    967                 DISPLAY_LIST_LOGD(
    968                         "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
    969                         (char*) indent, OP_NAMES[op], matrix,
    970                         matrix->get(0), matrix->get(1), matrix->get(2),
    971                         matrix->get(3), matrix->get(4), matrix->get(5),
    972                         matrix->get(6), matrix->get(7), matrix->get(8));
    973                 renderer.concatMatrix(matrix);
    974             }
    975             break;
    976             case ClipRect: {
    977                 float f1 = getFloat();
    978                 float f2 = getFloat();
    979                 float f3 = getFloat();
    980                 float f4 = getFloat();
    981                 int32_t regionOp = getInt();
    982                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
    983                         f1, f2, f3, f4, regionOp);
    984                 renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
    985             }
    986             break;
    987             case DrawDisplayList: {
    988                 DisplayList* displayList = getDisplayList();
    989                 int32_t flags = getInt();
    990                 DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
    991                         displayList, mWidth, mHeight, flags, level + 1);
    992                 drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
    993             }
    994             break;
    995             case DrawLayer: {
    996                 Layer* layer = (Layer*) getInt();
    997                 float x = getFloat();
    998                 float y = getFloat();
    999                 SkPaint* paint = getPaint(renderer);
   1000                 if (mCaching) {
   1001                     paint->setAlpha(mMultipliedAlpha);
   1002                 }
   1003                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
   1004                         layer, x, y, paint);
   1005                 drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
   1006             }
   1007             break;
   1008             case DrawBitmap: {
   1009                 SkBitmap* bitmap = getBitmap();
   1010                 float x = getFloat();
   1011                 float y = getFloat();
   1012                 SkPaint* paint = getPaint(renderer);
   1013                 if (mCaching) {
   1014                     paint->setAlpha(mMultipliedAlpha);
   1015                 }
   1016                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
   1017                         bitmap, x, y, paint);
   1018                 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
   1019             }
   1020             break;
   1021             case DrawBitmapMatrix: {
   1022                 SkBitmap* bitmap = getBitmap();
   1023                 SkMatrix* matrix = getMatrix();
   1024                 SkPaint* paint = getPaint(renderer);
   1025                 DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
   1026                         bitmap, matrix, paint);
   1027                 drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
   1028             }
   1029             break;
   1030             case DrawBitmapRect: {
   1031                 SkBitmap* bitmap = getBitmap();
   1032                 float f1 = getFloat();
   1033                 float f2 = getFloat();
   1034                 float f3 = getFloat();
   1035                 float f4 = getFloat();
   1036                 float f5 = getFloat();
   1037                 float f6 = getFloat();
   1038                 float f7 = getFloat();
   1039                 float f8 = getFloat();
   1040                 SkPaint* paint = getPaint(renderer);
   1041                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
   1042                         (char*) indent, OP_NAMES[op], bitmap,
   1043                         f1, f2, f3, f4, f5, f6, f7, f8,paint);
   1044                 drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
   1045             }
   1046             break;
   1047             case DrawBitmapData: {
   1048                 SkBitmap* bitmap = getBitmapData();
   1049                 float x = getFloat();
   1050                 float y = getFloat();
   1051                 SkPaint* paint = getPaint(renderer);
   1052                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
   1053                         bitmap, x, y, paint);
   1054                 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
   1055             }
   1056             break;
   1057             case DrawBitmapMesh: {
   1058                 int32_t verticesCount = 0;
   1059                 uint32_t colorsCount = 0;
   1060 
   1061                 SkBitmap* bitmap = getBitmap();
   1062                 uint32_t meshWidth = getInt();
   1063                 uint32_t meshHeight = getInt();
   1064                 float* vertices = getFloats(verticesCount);
   1065                 bool hasColors = getInt();
   1066                 int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
   1067                 SkPaint* paint = getPaint(renderer);
   1068 
   1069                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1070                 drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
   1071                         colors, paint);
   1072             }
   1073             break;
   1074             case DrawPatch: {
   1075                 int32_t* xDivs = NULL;
   1076                 int32_t* yDivs = NULL;
   1077                 uint32_t* colors = NULL;
   1078                 uint32_t xDivsCount = 0;
   1079                 uint32_t yDivsCount = 0;
   1080                 int8_t numColors = 0;
   1081 
   1082                 SkBitmap* bitmap = getBitmap();
   1083 
   1084                 xDivs = getInts(xDivsCount);
   1085                 yDivs = getInts(yDivsCount);
   1086                 colors = getUInts(numColors);
   1087 
   1088                 float left = getFloat();
   1089                 float top = getFloat();
   1090                 float right = getFloat();
   1091                 float bottom = getFloat();
   1092                 SkPaint* paint = getPaint(renderer);
   1093 
   1094                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1095                 drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
   1096                         xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint);
   1097             }
   1098             break;
   1099             case DrawColor: {
   1100                 int32_t color = getInt();
   1101                 int32_t xferMode = getInt();
   1102                 DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
   1103                 drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
   1104             }
   1105             break;
   1106             case DrawRect: {
   1107                 float f1 = getFloat();
   1108                 float f2 = getFloat();
   1109                 float f3 = getFloat();
   1110                 float f4 = getFloat();
   1111                 SkPaint* paint = getPaint(renderer);
   1112                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
   1113                         f1, f2, f3, f4, paint);
   1114                 drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
   1115             }
   1116             break;
   1117             case DrawRoundRect: {
   1118                 float f1 = getFloat();
   1119                 float f2 = getFloat();
   1120                 float f3 = getFloat();
   1121                 float f4 = getFloat();
   1122                 float f5 = getFloat();
   1123                 float f6 = getFloat();
   1124                 SkPaint* paint = getPaint(renderer);
   1125                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
   1126                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
   1127                 drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
   1128             }
   1129             break;
   1130             case DrawCircle: {
   1131                 float f1 = getFloat();
   1132                 float f2 = getFloat();
   1133                 float f3 = getFloat();
   1134                 SkPaint* paint = getPaint(renderer);
   1135                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
   1136                         (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
   1137                 drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
   1138             }
   1139             break;
   1140             case DrawOval: {
   1141                 float f1 = getFloat();
   1142                 float f2 = getFloat();
   1143                 float f3 = getFloat();
   1144                 float f4 = getFloat();
   1145                 SkPaint* paint = getPaint(renderer);
   1146                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
   1147                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
   1148                 drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
   1149             }
   1150             break;
   1151             case DrawArc: {
   1152                 float f1 = getFloat();
   1153                 float f2 = getFloat();
   1154                 float f3 = getFloat();
   1155                 float f4 = getFloat();
   1156                 float f5 = getFloat();
   1157                 float f6 = getFloat();
   1158                 int32_t i1 = getInt();
   1159                 SkPaint* paint = getPaint(renderer);
   1160                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
   1161                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
   1162                 drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
   1163             }
   1164             break;
   1165             case DrawPath: {
   1166                 SkPath* path = getPath();
   1167                 SkPaint* paint = getPaint(renderer);
   1168                 DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
   1169                 drawGlStatus |= renderer.drawPath(path, paint);
   1170             }
   1171             break;
   1172             case DrawLines: {
   1173                 int32_t count = 0;
   1174                 float* points = getFloats(count);
   1175                 SkPaint* paint = getPaint(renderer);
   1176                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1177                 drawGlStatus |= renderer.drawLines(points, count, paint);
   1178             }
   1179             break;
   1180             case DrawPoints: {
   1181                 int32_t count = 0;
   1182                 float* points = getFloats(count);
   1183                 SkPaint* paint = getPaint(renderer);
   1184                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1185                 drawGlStatus |= renderer.drawPoints(points, count, paint);
   1186             }
   1187             break;
   1188             case DrawText: {
   1189                 getText(&text);
   1190                 int32_t count = getInt();
   1191                 float x = getFloat();
   1192                 float y = getFloat();
   1193                 SkPaint* paint = getPaint(renderer);
   1194                 float length = getFloat();
   1195                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
   1196                         OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
   1197                 drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y,
   1198                         paint, length);
   1199             }
   1200             break;
   1201             case DrawTextOnPath: {
   1202                 getText(&text);
   1203                 int32_t count = getInt();
   1204                 SkPath* path = getPath();
   1205                 float hOffset = getFloat();
   1206                 float vOffset = getFloat();
   1207                 SkPaint* paint = getPaint(renderer);
   1208                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
   1209                     text.text(), text.length(), count, paint);
   1210                 drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
   1211                         hOffset, vOffset, paint);
   1212             }
   1213             break;
   1214             case DrawPosText: {
   1215                 getText(&text);
   1216                 int32_t count = getInt();
   1217                 int32_t positionsCount = 0;
   1218                 float* positions = getFloats(positionsCount);
   1219                 SkPaint* paint = getPaint(renderer);
   1220                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
   1221                         OP_NAMES[op], text.text(), text.length(), count, paint);
   1222                 drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
   1223                         positions, paint);
   1224             }
   1225             break;
   1226             case ResetShader: {
   1227                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1228                 renderer.resetShader();
   1229             }
   1230             break;
   1231             case SetupShader: {
   1232                 SkiaShader* shader = getShader();
   1233                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
   1234                 renderer.setupShader(shader);
   1235             }
   1236             break;
   1237             case ResetColorFilter: {
   1238                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1239                 renderer.resetColorFilter();
   1240             }
   1241             break;
   1242             case SetupColorFilter: {
   1243                 SkiaColorFilter *colorFilter = getColorFilter();
   1244                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
   1245                 renderer.setupColorFilter(colorFilter);
   1246             }
   1247             break;
   1248             case ResetShadow: {
   1249                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1250                 renderer.resetShadow();
   1251             }
   1252             break;
   1253             case SetupShadow: {
   1254                 float radius = getFloat();
   1255                 float dx = getFloat();
   1256                 float dy = getFloat();
   1257                 int32_t color = getInt();
   1258                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
   1259                         radius, dx, dy, color);
   1260                 renderer.setupShadow(radius, dx, dy, color);
   1261             }
   1262             break;
   1263             case ResetPaintFilter: {
   1264                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
   1265                 renderer.resetPaintFilter();
   1266             }
   1267             break;
   1268             case SetupPaintFilter: {
   1269                 int32_t clearBits = getInt();
   1270                 int32_t setBits = getInt();
   1271                 DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
   1272                         clearBits, setBits);
   1273                 renderer.setupPaintFilter(clearBits, setBits);
   1274             }
   1275             break;
   1276             default:
   1277                 DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
   1278                         (char*) indent, OP_NAMES[op]);
   1279                 break;
   1280         }
   1281     }
   1282 
   1283     DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
   1284     renderer.restoreToCount(restoreTo);
   1285     renderer.endMark();
   1286 
   1287     DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
   1288             drawGlStatus);
   1289     return drawGlStatus;
   1290 }
   1291 
   1292 ///////////////////////////////////////////////////////////////////////////////
   1293 // Base structure
   1294 ///////////////////////////////////////////////////////////////////////////////
   1295 
   1296 DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
   1297         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
   1298 }
   1299 
   1300 DisplayListRenderer::~DisplayListRenderer() {
   1301     reset();
   1302 }
   1303 
   1304 void DisplayListRenderer::reset() {
   1305     mWriter.reset();
   1306 
   1307     Caches& caches = Caches::getInstance();
   1308     for (size_t i = 0; i < mBitmapResources.size(); i++) {
   1309         caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
   1310     }
   1311     mBitmapResources.clear();
   1312 
   1313     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
   1314         SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
   1315         caches.resourceCache.decrementRefcount(bitmap);
   1316     }
   1317     mOwnedBitmapResources.clear();
   1318 
   1319     for (size_t i = 0; i < mFilterResources.size(); i++) {
   1320         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
   1321     }
   1322     mFilterResources.clear();
   1323 
   1324     for (size_t i = 0; i < mShaders.size(); i++) {
   1325         caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
   1326     }
   1327     mShaders.clear();
   1328     mShaderMap.clear();
   1329 
   1330     for (size_t i = 0; i < mSourcePaths.size(); i++) {
   1331         caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
   1332     }
   1333     mSourcePaths.clear();
   1334 
   1335     mPaints.clear();
   1336     mPaintMap.clear();
   1337 
   1338     mPaths.clear();
   1339     mPathMap.clear();
   1340 
   1341     mMatrices.clear();
   1342 
   1343     mHasDrawOps = false;
   1344 }
   1345 
   1346 ///////////////////////////////////////////////////////////////////////////////
   1347 // Operations
   1348 ///////////////////////////////////////////////////////////////////////////////
   1349 
   1350 DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
   1351     if (!displayList) {
   1352         displayList = new DisplayList(*this);
   1353     } else {
   1354         displayList->initFromDisplayListRenderer(*this, true);
   1355     }
   1356     displayList->setRenderable(mHasDrawOps);
   1357     return displayList;
   1358 }
   1359 
   1360 bool DisplayListRenderer::isDeferred() {
   1361     return true;
   1362 }
   1363 
   1364 void DisplayListRenderer::setViewport(int width, int height) {
   1365     mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
   1366 
   1367     mWidth = width;
   1368     mHeight = height;
   1369 }
   1370 
   1371 int DisplayListRenderer::prepareDirty(float left, float top,
   1372         float right, float bottom, bool opaque) {
   1373     mSnapshot = new Snapshot(mFirstSnapshot,
   1374             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
   1375     mSaveCount = 1;
   1376     mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
   1377     mRestoreSaveCount = -1;
   1378     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
   1379 }
   1380 
   1381 void DisplayListRenderer::finish() {
   1382     insertRestoreToCount();
   1383     insertTranlate();
   1384 }
   1385 
   1386 void DisplayListRenderer::interrupt() {
   1387 }
   1388 
   1389 void DisplayListRenderer::resume() {
   1390 }
   1391 
   1392 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
   1393     // Ignore dirty during recording, it matters only when we replay
   1394     addOp(DisplayList::DrawGLFunction);
   1395     addInt((int) functor);
   1396     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
   1397 }
   1398 
   1399 int DisplayListRenderer::save(int flags) {
   1400     addOp(DisplayList::Save);
   1401     addInt(flags);
   1402     return OpenGLRenderer::save(flags);
   1403 }
   1404 
   1405 void DisplayListRenderer::restore() {
   1406     if (mRestoreSaveCount < 0) {
   1407         restoreToCount(getSaveCount() - 1);
   1408         return;
   1409     }
   1410 
   1411     mRestoreSaveCount--;
   1412     insertTranlate();
   1413     OpenGLRenderer::restore();
   1414 }
   1415 
   1416 void DisplayListRenderer::restoreToCount(int saveCount) {
   1417     mRestoreSaveCount = saveCount;
   1418     insertTranlate();
   1419     OpenGLRenderer::restoreToCount(saveCount);
   1420 }
   1421 
   1422 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
   1423         SkPaint* p, int flags) {
   1424     addOp(DisplayList::SaveLayer);
   1425     addBounds(left, top, right, bottom);
   1426     addPaint(p);
   1427     addInt(flags);
   1428     return OpenGLRenderer::save(flags);
   1429 }
   1430 
   1431 int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
   1432         int alpha, int flags) {
   1433     addOp(DisplayList::SaveLayerAlpha);
   1434     addBounds(left, top, right, bottom);
   1435     addInt(alpha);
   1436     addInt(flags);
   1437     return OpenGLRenderer::save(flags);
   1438 }
   1439 
   1440 void DisplayListRenderer::translate(float dx, float dy) {
   1441     mHasTranslate = true;
   1442     mTranslateX += dx;
   1443     mTranslateY += dy;
   1444     insertRestoreToCount();
   1445     OpenGLRenderer::translate(dx, dy);
   1446 }
   1447 
   1448 void DisplayListRenderer::rotate(float degrees) {
   1449     addOp(DisplayList::Rotate);
   1450     addFloat(degrees);
   1451     OpenGLRenderer::rotate(degrees);
   1452 }
   1453 
   1454 void DisplayListRenderer::scale(float sx, float sy) {
   1455     addOp(DisplayList::Scale);
   1456     addPoint(sx, sy);
   1457     OpenGLRenderer::scale(sx, sy);
   1458 }
   1459 
   1460 void DisplayListRenderer::skew(float sx, float sy) {
   1461     addOp(DisplayList::Skew);
   1462     addPoint(sx, sy);
   1463     OpenGLRenderer::skew(sx, sy);
   1464 }
   1465 
   1466 void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
   1467     addOp(DisplayList::SetMatrix);
   1468     addMatrix(matrix);
   1469     OpenGLRenderer::setMatrix(matrix);
   1470 }
   1471 
   1472 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
   1473     addOp(DisplayList::ConcatMatrix);
   1474     addMatrix(matrix);
   1475     OpenGLRenderer::concatMatrix(matrix);
   1476 }
   1477 
   1478 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
   1479         SkRegion::Op op) {
   1480     addOp(DisplayList::ClipRect);
   1481     addBounds(left, top, right, bottom);
   1482     addInt(op);
   1483     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
   1484 }
   1485 
   1486 status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
   1487         Rect& dirty, int32_t flags, uint32_t level) {
   1488     // dirty is an out parameter and should not be recorded,
   1489     // it matters only when replaying the display list
   1490 
   1491     addOp(DisplayList::DrawDisplayList);
   1492     addDisplayList(displayList);
   1493     addInt(flags);
   1494     return DrawGlInfo::kStatusDone;
   1495 }
   1496 
   1497 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
   1498     addOp(DisplayList::DrawLayer);
   1499     addInt((int) layer);
   1500     addPoint(x, y);
   1501     addPaint(paint);
   1502     return DrawGlInfo::kStatusDone;
   1503 }
   1504 
   1505 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
   1506     const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
   1507     uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
   1508     addBitmap(bitmap);
   1509     addPoint(left, top);
   1510     addPaint(paint);
   1511     addSkip(location);
   1512     return DrawGlInfo::kStatusDone;
   1513 }
   1514 
   1515 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
   1516     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
   1517     const mat4 transform(*matrix);
   1518     transform.mapRect(r);
   1519 
   1520     const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
   1521     uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
   1522     addBitmap(bitmap);
   1523     addMatrix(matrix);
   1524     addPaint(paint);
   1525     addSkip(location);
   1526     return DrawGlInfo::kStatusDone;
   1527 }
   1528 
   1529 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
   1530         float srcRight, float srcBottom, float dstLeft, float dstTop,
   1531         float dstRight, float dstBottom, SkPaint* paint) {
   1532     const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
   1533     uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
   1534     addBitmap(bitmap);
   1535     addBounds(srcLeft, srcTop, srcRight, srcBottom);
   1536     addBounds(dstLeft, dstTop, dstRight, dstBottom);
   1537     addPaint(paint);
   1538     addSkip(location);
   1539     return DrawGlInfo::kStatusDone;
   1540 }
   1541 
   1542 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
   1543         SkPaint* paint) {
   1544     const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
   1545     uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
   1546     addBitmapData(bitmap);
   1547     addPoint(left, top);
   1548     addPaint(paint);
   1549     addSkip(location);
   1550     return DrawGlInfo::kStatusDone;
   1551 }
   1552 
   1553 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
   1554         float* vertices, int* colors, SkPaint* paint) {
   1555     addOp(DisplayList::DrawBitmapMesh);
   1556     addBitmap(bitmap);
   1557     addInt(meshWidth);
   1558     addInt(meshHeight);
   1559     addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
   1560     if (colors) {
   1561         addInt(1);
   1562         addInts(colors, (meshWidth + 1) * (meshHeight + 1));
   1563     } else {
   1564         addInt(0);
   1565     }
   1566     addPaint(paint);
   1567     return DrawGlInfo::kStatusDone;
   1568 }
   1569 
   1570 status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
   1571         const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
   1572         int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
   1573     const bool reject = quickReject(left, top, right, bottom);
   1574     uint32_t* location = addOp(DisplayList::DrawPatch, reject);
   1575     addBitmap(bitmap);
   1576     addInts(xDivs, width);
   1577     addInts(yDivs, height);
   1578     addUInts(colors, numColors);
   1579     addBounds(left, top, right, bottom);
   1580     addPaint(paint);
   1581     addSkip(location);
   1582     return DrawGlInfo::kStatusDone;
   1583 }
   1584 
   1585 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
   1586     addOp(DisplayList::DrawColor);
   1587     addInt(color);
   1588     addInt(mode);
   1589     return DrawGlInfo::kStatusDone;
   1590 }
   1591 
   1592 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
   1593         SkPaint* paint) {
   1594     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
   1595             quickReject(left, top, right, bottom);
   1596     uint32_t* location = addOp(DisplayList::DrawRect, reject);
   1597     addBounds(left, top, right, bottom);
   1598     addPaint(paint);
   1599     addSkip(location);
   1600     return DrawGlInfo::kStatusDone;
   1601 }
   1602 
   1603 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
   1604         float rx, float ry, SkPaint* paint) {
   1605     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
   1606             quickReject(left, top, right, bottom);
   1607     uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
   1608     addBounds(left, top, right, bottom);
   1609     addPoint(rx, ry);
   1610     addPaint(paint);
   1611     addSkip(location);
   1612     return DrawGlInfo::kStatusDone;
   1613 }
   1614 
   1615 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
   1616     addOp(DisplayList::DrawCircle);
   1617     addPoint(x, y);
   1618     addFloat(radius);
   1619     addPaint(paint);
   1620     return DrawGlInfo::kStatusDone;
   1621 }
   1622 
   1623 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
   1624         SkPaint* paint) {
   1625     addOp(DisplayList::DrawOval);
   1626     addBounds(left, top, right, bottom);
   1627     addPaint(paint);
   1628     return DrawGlInfo::kStatusDone;
   1629 }
   1630 
   1631 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
   1632         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
   1633     addOp(DisplayList::DrawArc);
   1634     addBounds(left, top, right, bottom);
   1635     addPoint(startAngle, sweepAngle);
   1636     addInt(useCenter ? 1 : 0);
   1637     addPaint(paint);
   1638     return DrawGlInfo::kStatusDone;
   1639 }
   1640 
   1641 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
   1642     float left, top, offset;
   1643     uint32_t width, height;
   1644     computePathBounds(path, paint, left, top, offset, width, height);
   1645 
   1646     left -= offset;
   1647     top -= offset;
   1648 
   1649     const bool reject = quickReject(left, top, left + width, top + height);
   1650     uint32_t* location = addOp(DisplayList::DrawPath, reject);
   1651     addPath(path);
   1652     addPaint(paint);
   1653     addSkip(location);
   1654     return DrawGlInfo::kStatusDone;
   1655 }
   1656 
   1657 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
   1658     addOp(DisplayList::DrawLines);
   1659     addFloats(points, count);
   1660     addPaint(paint);
   1661     return DrawGlInfo::kStatusDone;
   1662 }
   1663 
   1664 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
   1665     addOp(DisplayList::DrawPoints);
   1666     addFloats(points, count);
   1667     addPaint(paint);
   1668     return DrawGlInfo::kStatusDone;
   1669 }
   1670 
   1671 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
   1672         float x, float y, SkPaint* paint, float length) {
   1673     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
   1674 
   1675     // TODO: We should probably make a copy of the paint instead of modifying
   1676     //       it; modifying the paint will change its generationID the first
   1677     //       time, which might impact caches. More investigation needed to
   1678     //       see if it matters.
   1679     //       If we make a copy, then drawTextDecorations() should *not* make
   1680     //       its own copy as it does right now.
   1681     // Beware: this needs Glyph encoding (already done on the Paint constructor)
   1682     paint->setAntiAlias(true);
   1683     if (length < 0.0f) length = paint->measureText(text, bytesCount);
   1684 
   1685     bool reject = false;
   1686     if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
   1687         SkPaint::FontMetrics metrics;
   1688         paint->getFontMetrics(&metrics, 0.0f);
   1689         reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
   1690     }
   1691 
   1692     uint32_t* location = addOp(DisplayList::DrawText, reject);
   1693     addText(text, bytesCount);
   1694     addInt(count);
   1695     addPoint(x, y);
   1696     addPaint(paint);
   1697     addFloat(length);
   1698     addSkip(location);
   1699     return DrawGlInfo::kStatusDone;
   1700 }
   1701 
   1702 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
   1703         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
   1704     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
   1705     addOp(DisplayList::DrawTextOnPath);
   1706     addText(text, bytesCount);
   1707     addInt(count);
   1708     addPath(path);
   1709     addFloat(hOffset);
   1710     addFloat(vOffset);
   1711     paint->setAntiAlias(true);
   1712     addPaint(paint);
   1713     return DrawGlInfo::kStatusDone;
   1714 }
   1715 
   1716 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
   1717         const float* positions, SkPaint* paint) {
   1718     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
   1719     addOp(DisplayList::DrawPosText);
   1720     addText(text, bytesCount);
   1721     addInt(count);
   1722     addFloats(positions, count * 2);
   1723     paint->setAntiAlias(true);
   1724     addPaint(paint);
   1725     return DrawGlInfo::kStatusDone;
   1726 }
   1727 
   1728 void DisplayListRenderer::resetShader() {
   1729     addOp(DisplayList::ResetShader);
   1730 }
   1731 
   1732 void DisplayListRenderer::setupShader(SkiaShader* shader) {
   1733     addOp(DisplayList::SetupShader);
   1734     addShader(shader);
   1735 }
   1736 
   1737 void DisplayListRenderer::resetColorFilter() {
   1738     addOp(DisplayList::ResetColorFilter);
   1739 }
   1740 
   1741 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
   1742     addOp(DisplayList::SetupColorFilter);
   1743     addColorFilter(filter);
   1744 }
   1745 
   1746 void DisplayListRenderer::resetShadow() {
   1747     addOp(DisplayList::ResetShadow);
   1748 }
   1749 
   1750 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
   1751     addOp(DisplayList::SetupShadow);
   1752     addFloat(radius);
   1753     addPoint(dx, dy);
   1754     addInt(color);
   1755 }
   1756 
   1757 void DisplayListRenderer::resetPaintFilter() {
   1758     addOp(DisplayList::ResetPaintFilter);
   1759 }
   1760 
   1761 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
   1762     addOp(DisplayList::SetupPaintFilter);
   1763     addInt(clearBits);
   1764     addInt(setBits);
   1765 }
   1766 
   1767 }; // namespace uirenderer
   1768 }; // namespace android
   1769