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