DisplayListRenderer.cpp revision 95c21d0546e36ade3e0601394f5b625541836545
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
27namespace android {
28namespace uirenderer {
29
30///////////////////////////////////////////////////////////////////////////////
31// Display list
32///////////////////////////////////////////////////////////////////////////////
33
34const 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
78void 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
97DisplayList::DisplayList(const DisplayListRenderer& recorder) :
98    mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
99    mStaticMatrix(NULL), mAnimationMatrix(NULL) {
100
101    initFromDisplayListRenderer(recorder);
102}
103
104DisplayList::~DisplayList() {
105    clearResources();
106}
107
108void 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
137void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
138    if (displayList) {
139        DISPLAY_LIST_LOGD("Deferring display list destruction");
140        Caches::getInstance().deleteDisplayListDeferred(displayList);
141    }
142}
143
144void 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
206void 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
277void DisplayList::init() {
278    mSize = 0;
279    mIsRenderable = true;
280}
281
282size_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 */
290void 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                int alpha = getInt();
490                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
491                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
492                        left, top, right, bottom);
493            }
494            break;
495            case DrawColor: {
496                int color = getInt();
497                int xferMode = getInt();
498                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
499            }
500            break;
501            case DrawRect: {
502                float f1 = getFloat();
503                float f2 = getFloat();
504                float f3 = getFloat();
505                float f4 = getFloat();
506                SkPaint* paint = getPaint(renderer);
507                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
508                        f1, f2, f3, f4, paint);
509            }
510            break;
511            case DrawRoundRect: {
512                float f1 = getFloat();
513                float f2 = getFloat();
514                float f3 = getFloat();
515                float f4 = getFloat();
516                float f5 = getFloat();
517                float f6 = getFloat();
518                SkPaint* paint = getPaint(renderer);
519                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
520                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
521            }
522            break;
523            case DrawCircle: {
524                float f1 = getFloat();
525                float f2 = getFloat();
526                float f3 = getFloat();
527                SkPaint* paint = getPaint(renderer);
528                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
529                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
530            }
531            break;
532            case DrawOval: {
533                float f1 = getFloat();
534                float f2 = getFloat();
535                float f3 = getFloat();
536                float f4 = getFloat();
537                SkPaint* paint = getPaint(renderer);
538                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
539                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
540            }
541            break;
542            case DrawArc: {
543                float f1 = getFloat();
544                float f2 = getFloat();
545                float f3 = getFloat();
546                float f4 = getFloat();
547                float f5 = getFloat();
548                float f6 = getFloat();
549                int i1 = getInt();
550                SkPaint* paint = getPaint(renderer);
551                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
552                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
553            }
554            break;
555            case DrawPath: {
556                SkPath* path = getPath();
557                SkPaint* paint = getPaint(renderer);
558                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
559            }
560            break;
561            case DrawLines: {
562                int count = 0;
563                float* points = getFloats(count);
564                SkPaint* paint = getPaint(renderer);
565                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
566            }
567            break;
568            case DrawPoints: {
569                int count = 0;
570                float* points = getFloats(count);
571                SkPaint* paint = getPaint(renderer);
572                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
573            }
574            break;
575            case DrawText: {
576                getText(&text);
577                int32_t count = getInt();
578                float x = getFloat();
579                float y = getFloat();
580                SkPaint* paint = getPaint(renderer);
581                float length = getFloat();
582                ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
583                        text.text(), text.length(), count, x, y, paint, length);
584            }
585            break;
586            case DrawTextOnPath: {
587                getText(&text);
588                int32_t count = getInt();
589                SkPath* path = getPath();
590                float hOffset = getFloat();
591                float vOffset = getFloat();
592                SkPaint* paint = getPaint(renderer);
593                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
594                    text.text(), text.length(), count, paint);
595            }
596            break;
597            case DrawPosText: {
598                getText(&text);
599                int count = getInt();
600                int positionsCount = 0;
601                float* positions = getFloats(positionsCount);
602                SkPaint* paint = getPaint(renderer);
603                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
604                        text.text(), text.length(), count, paint);
605            }
606            case ResetShader: {
607                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
608            }
609            break;
610            case SetupShader: {
611                SkiaShader* shader = getShader();
612                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
613            }
614            break;
615            case ResetColorFilter: {
616                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
617            }
618            break;
619            case SetupColorFilter: {
620                SkiaColorFilter *colorFilter = getColorFilter();
621                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
622            }
623            break;
624            case ResetShadow: {
625                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
626            }
627            break;
628            case SetupShadow: {
629                float radius = getFloat();
630                float dx = getFloat();
631                float dy = getFloat();
632                int color = getInt();
633                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
634                        radius, dx, dy, color);
635            }
636            break;
637            case ResetPaintFilter: {
638                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
639            }
640            break;
641            case SetupPaintFilter: {
642                int clearBits = getInt();
643                int setBits = getInt();
644                ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
645            }
646            break;
647            default:
648                ALOGD("Display List error: op not handled: %s%s",
649                        (char*) indent, OP_NAMES[op]);
650                break;
651        }
652    }
653    ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
654}
655
656void DisplayList::updateMatrix() {
657    if (mMatrixDirty) {
658        if (!mTransformMatrix) {
659            mTransformMatrix = new SkMatrix();
660        }
661        if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
662            mTransformMatrix->reset();
663        } else {
664            if (!mPivotExplicitlySet) {
665                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
666                    mPrevWidth = mWidth;
667                    mPrevHeight = mHeight;
668                    mPivotX = mPrevWidth / 2;
669                    mPivotY = mPrevHeight / 2;
670                }
671            }
672            if ((mMatrixFlags & ROTATION_3D) == 0) {
673                mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
674                mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
675                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
676            } else {
677                if (!mTransformCamera) {
678                    mTransformCamera = new Sk3DView();
679                    mTransformMatrix3D = new SkMatrix();
680                }
681                mTransformMatrix->reset();
682                mTransformCamera->save();
683                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
684                mTransformCamera->rotateX(mRotationX);
685                mTransformCamera->rotateY(mRotationY);
686                mTransformCamera->rotateZ(-mRotation);
687                mTransformCamera->getMatrix(mTransformMatrix3D);
688                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
689                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
690                        mPivotY + mTranslationY);
691                mTransformMatrix->postConcat(*mTransformMatrix3D);
692                mTransformCamera->restore();
693            }
694        }
695        mMatrixDirty = false;
696    }
697}
698
699void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
700    updateMatrix();
701    if (mLeft != 0 || mTop != 0) {
702        ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
703    }
704    if (mStaticMatrix) {
705        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
706                indent, "ConcatMatrix (static)", mStaticMatrix,
707                mStaticMatrix->get(0), mStaticMatrix->get(1),
708                mStaticMatrix->get(2), mStaticMatrix->get(3),
709                mStaticMatrix->get(4), mStaticMatrix->get(5),
710                mStaticMatrix->get(6), mStaticMatrix->get(7),
711                mStaticMatrix->get(8));
712    }
713    if (mAnimationMatrix) {
714        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
715                indent, "ConcatMatrix (animation)", mAnimationMatrix,
716                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
717                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
718                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
719                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
720                mAnimationMatrix->get(8));
721    }
722    if (mMatrixFlags != 0) {
723        if (mMatrixFlags == TRANSLATION) {
724            ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
725        } else {
726            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
727                    indent, "ConcatMatrix", mTransformMatrix,
728                    mTransformMatrix->get(0), mTransformMatrix->get(1),
729                    mTransformMatrix->get(2), mTransformMatrix->get(3),
730                    mTransformMatrix->get(4), mTransformMatrix->get(5),
731                    mTransformMatrix->get(6), mTransformMatrix->get(7),
732                    mTransformMatrix->get(8));
733        }
734    }
735    if (mAlpha < 1 && !mCaching) {
736        // TODO: should be able to store the size of a DL at record time and not
737        // have to pass it into this call. In fact, this information might be in the
738        // location/size info that we store with the new native transform data.
739        int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
740        if (mClipChildren) {
741            flags |= SkCanvas::kClipToLayer_SaveFlag;
742        }
743        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
744                (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
745                mMultipliedAlpha, flags);
746    }
747    if (mClipChildren) {
748        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
749                (float) mRight - mLeft, (float) mBottom - mTop);
750    }
751}
752
753void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
754#if DEBUG_DISPLAY_LIST
755        uint32_t count = (level + 1) * 2;
756        char indent[count + 1];
757        for (uint32_t i = 0; i < count; i++) {
758            indent[i] = ' ';
759        }
760        indent[count] = '\0';
761#endif
762    updateMatrix();
763    if (mLeft != 0 || mTop != 0) {
764        DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
765        renderer.translate(mLeft, mTop);
766    }
767    if (mStaticMatrix) {
768        DISPLAY_LIST_LOGD(
769                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
770                indent, "ConcatMatrix (static)", mStaticMatrix,
771                mStaticMatrix->get(0), mStaticMatrix->get(1),
772                mStaticMatrix->get(2), mStaticMatrix->get(3),
773                mStaticMatrix->get(4), mStaticMatrix->get(5),
774                mStaticMatrix->get(6), mStaticMatrix->get(7),
775                mStaticMatrix->get(8));
776        renderer.concatMatrix(mStaticMatrix);
777    } else if (mAnimationMatrix) {
778        DISPLAY_LIST_LOGD(
779                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
780                indent, "ConcatMatrix (animation)", mAnimationMatrix,
781                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
782                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
783                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
784                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
785                mAnimationMatrix->get(8));
786        renderer.concatMatrix(mAnimationMatrix);
787    }
788    if (mMatrixFlags != 0) {
789        if (mMatrixFlags == TRANSLATION) {
790            DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
791            renderer.translate(mTranslationX, mTranslationY);
792        } else {
793            DISPLAY_LIST_LOGD(
794                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
795                    indent, "ConcatMatrix", mTransformMatrix,
796                    mTransformMatrix->get(0), mTransformMatrix->get(1),
797                    mTransformMatrix->get(2), mTransformMatrix->get(3),
798                    mTransformMatrix->get(4), mTransformMatrix->get(5),
799                    mTransformMatrix->get(6), mTransformMatrix->get(7),
800                    mTransformMatrix->get(8));
801            renderer.concatMatrix(mTransformMatrix);
802        }
803    }
804    if (mAlpha < 1 && !mCaching) {
805        if (!mHasOverlappingRendering) {
806            DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
807            renderer.setAlpha(mAlpha);
808        } else {
809            // TODO: should be able to store the size of a DL at record time and not
810            // have to pass it into this call. In fact, this information might be in the
811            // location/size info that we store with the new native transform data.
812            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
813            if (mClipChildren) {
814                flags |= SkCanvas::kClipToLayer_SaveFlag;
815            }
816            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
817                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
818                    mMultipliedAlpha, flags);
819            renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
820                    mMultipliedAlpha, flags);
821        }
822    }
823    if (mClipChildren) {
824        DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
825                (float) mRight - mLeft, (float) mBottom - mTop);
826        renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
827                SkRegion::kIntersect_Op);
828    }
829}
830
831/**
832 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
833 * in the output() function, since that function processes the same list of opcodes for the
834 * purposes of logging display list info for a given view.
835 */
836status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
837    status_t drawGlStatus = DrawGlInfo::kStatusDone;
838    TextContainer text;
839    mReader.rewind();
840
841#if DEBUG_DISPLAY_LIST
842    uint32_t count = (level + 1) * 2;
843    char indent[count + 1];
844    for (uint32_t i = 0; i < count; i++) {
845        indent[i] = ' ';
846    }
847    indent[count] = '\0';
848    Rect* clipRect = renderer.getClipRect();
849    DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
850            (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
851            clipRect->right, clipRect->bottom);
852#endif
853
854    renderer.startMark(mName.string());
855
856    int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
857    DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
858            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
859    setViewProperties(renderer, level);
860
861    if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
862        DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
863        renderer.restoreToCount(restoreTo);
864        renderer.endMark();
865        return drawGlStatus;
866    }
867
868    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
869    int saveCount = renderer.getSaveCount() - 1;
870
871    while (!mReader.eof()) {
872        int op = mReader.readInt();
873        if (op & OP_MAY_BE_SKIPPED_MASK) {
874            int32_t skip = mReader.readInt();
875            if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
876                mReader.skip(skip);
877                DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
878                        OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
879                continue;
880            } else {
881                op &= ~OP_MAY_BE_SKIPPED_MASK;
882            }
883        }
884        logBuffer.writeCommand(level, op);
885
886#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
887        Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]);
888#endif
889
890        switch (op) {
891            case DrawGLFunction: {
892                Functor *functor = (Functor *) getInt();
893                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
894                renderer.startMark("GL functor");
895                drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
896                renderer.endMark();
897            }
898            break;
899            case Save: {
900                int32_t rendererNum = getInt();
901                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
902                renderer.save(rendererNum);
903            }
904            break;
905            case Restore: {
906                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
907                renderer.restore();
908            }
909            break;
910            case RestoreToCount: {
911                int32_t restoreCount = saveCount + getInt();
912                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
913                renderer.restoreToCount(restoreCount);
914            }
915            break;
916            case SaveLayer: {
917                float f1 = getFloat();
918                float f2 = getFloat();
919                float f3 = getFloat();
920                float f4 = getFloat();
921                SkPaint* paint = getPaint(renderer);
922                int32_t flags = getInt();
923                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
924                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
925                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
926            }
927            break;
928            case SaveLayerAlpha: {
929                float f1 = getFloat();
930                float f2 = getFloat();
931                float f3 = getFloat();
932                float f4 = getFloat();
933                int32_t alpha = getInt();
934                int32_t flags = getInt();
935                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
936                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
937                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
938            }
939            break;
940            case Translate: {
941                float f1 = getFloat();
942                float f2 = getFloat();
943                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
944                renderer.translate(f1, f2);
945            }
946            break;
947            case Rotate: {
948                float rotation = getFloat();
949                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
950                renderer.rotate(rotation);
951            }
952            break;
953            case Scale: {
954                float sx = getFloat();
955                float sy = getFloat();
956                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
957                renderer.scale(sx, sy);
958            }
959            break;
960            case Skew: {
961                float sx = getFloat();
962                float sy = getFloat();
963                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
964                renderer.skew(sx, sy);
965            }
966            break;
967            case SetMatrix: {
968                SkMatrix* matrix = getMatrix();
969                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
970                renderer.setMatrix(matrix);
971            }
972            break;
973            case ConcatMatrix: {
974                SkMatrix* matrix = getMatrix();
975                DISPLAY_LIST_LOGD(
976                        "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
977                        (char*) indent, OP_NAMES[op], matrix,
978                        matrix->get(0), matrix->get(1), matrix->get(2),
979                        matrix->get(3), matrix->get(4), matrix->get(5),
980                        matrix->get(6), matrix->get(7), matrix->get(8));
981                renderer.concatMatrix(matrix);
982            }
983            break;
984            case ClipRect: {
985                float f1 = getFloat();
986                float f2 = getFloat();
987                float f3 = getFloat();
988                float f4 = getFloat();
989                int32_t regionOp = getInt();
990                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
991                        f1, f2, f3, f4, regionOp);
992                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
993            }
994            break;
995            case DrawDisplayList: {
996                DisplayList* displayList = getDisplayList();
997                int32_t flags = getInt();
998                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
999                        displayList, mWidth, mHeight, flags, level + 1);
1000                drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
1001            }
1002            break;
1003            case DrawLayer: {
1004                Layer* layer = (Layer*) getInt();
1005                float x = getFloat();
1006                float y = getFloat();
1007                SkPaint* paint = getPaint(renderer);
1008                if (mCaching) {
1009                    paint->setAlpha(mMultipliedAlpha);
1010                }
1011                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1012                        layer, x, y, paint);
1013                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
1014            }
1015            break;
1016            case DrawBitmap: {
1017                SkBitmap* bitmap = getBitmap();
1018                float x = getFloat();
1019                float y = getFloat();
1020                SkPaint* paint = getPaint(renderer);
1021                if (mCaching) {
1022                    paint->setAlpha(mMultipliedAlpha);
1023                }
1024                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1025                        bitmap, x, y, paint);
1026                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1027            }
1028            break;
1029            case DrawBitmapMatrix: {
1030                SkBitmap* bitmap = getBitmap();
1031                SkMatrix* matrix = getMatrix();
1032                SkPaint* paint = getPaint(renderer);
1033                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
1034                        bitmap, matrix, paint);
1035                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
1036            }
1037            break;
1038            case DrawBitmapRect: {
1039                SkBitmap* bitmap = getBitmap();
1040                float f1 = getFloat();
1041                float f2 = getFloat();
1042                float f3 = getFloat();
1043                float f4 = getFloat();
1044                float f5 = getFloat();
1045                float f6 = getFloat();
1046                float f7 = getFloat();
1047                float f8 = getFloat();
1048                SkPaint* paint = getPaint(renderer);
1049                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1050                        (char*) indent, OP_NAMES[op], bitmap,
1051                        f1, f2, f3, f4, f5, f6, f7, f8,paint);
1052                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
1053            }
1054            break;
1055            case DrawBitmapData: {
1056                SkBitmap* bitmap = getBitmapData();
1057                float x = getFloat();
1058                float y = getFloat();
1059                SkPaint* paint = getPaint(renderer);
1060                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1061                        bitmap, x, y, paint);
1062                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1063            }
1064            break;
1065            case DrawBitmapMesh: {
1066                int32_t verticesCount = 0;
1067                uint32_t colorsCount = 0;
1068
1069                SkBitmap* bitmap = getBitmap();
1070                uint32_t meshWidth = getInt();
1071                uint32_t meshHeight = getInt();
1072                float* vertices = getFloats(verticesCount);
1073                bool hasColors = getInt();
1074                int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
1075                SkPaint* paint = getPaint(renderer);
1076
1077                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1078                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
1079                        colors, paint);
1080            }
1081            break;
1082            case DrawPatch: {
1083                int32_t* xDivs = NULL;
1084                int32_t* yDivs = NULL;
1085                uint32_t* colors = NULL;
1086                uint32_t xDivsCount = 0;
1087                uint32_t yDivsCount = 0;
1088                int8_t numColors = 0;
1089
1090                SkBitmap* bitmap = getBitmap();
1091
1092                xDivs = getInts(xDivsCount);
1093                yDivs = getInts(yDivsCount);
1094                colors = getUInts(numColors);
1095
1096                float left = getFloat();
1097                float top = getFloat();
1098                float right = getFloat();
1099                float bottom = getFloat();
1100
1101                int alpha = getInt();
1102                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
1103
1104                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1105                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
1106                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
1107                        alpha, mode);
1108            }
1109            break;
1110            case DrawColor: {
1111                int32_t color = getInt();
1112                int32_t xferMode = getInt();
1113                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
1114                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
1115            }
1116            break;
1117            case DrawRect: {
1118                float f1 = getFloat();
1119                float f2 = getFloat();
1120                float f3 = getFloat();
1121                float f4 = getFloat();
1122                SkPaint* paint = getPaint(renderer);
1123                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1124                        f1, f2, f3, f4, paint);
1125                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
1126            }
1127            break;
1128            case DrawRoundRect: {
1129                float f1 = getFloat();
1130                float f2 = getFloat();
1131                float f3 = getFloat();
1132                float f4 = getFloat();
1133                float f5 = getFloat();
1134                float f6 = getFloat();
1135                SkPaint* paint = getPaint(renderer);
1136                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1137                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
1138                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
1139            }
1140            break;
1141            case DrawCircle: {
1142                float f1 = getFloat();
1143                float f2 = getFloat();
1144                float f3 = getFloat();
1145                SkPaint* paint = getPaint(renderer);
1146                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
1147                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
1148                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
1149            }
1150            break;
1151            case DrawOval: {
1152                float f1 = getFloat();
1153                float f2 = getFloat();
1154                float f3 = getFloat();
1155                float f4 = getFloat();
1156                SkPaint* paint = getPaint(renderer);
1157                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
1158                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
1159                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
1160            }
1161            break;
1162            case DrawArc: {
1163                float f1 = getFloat();
1164                float f2 = getFloat();
1165                float f3 = getFloat();
1166                float f4 = getFloat();
1167                float f5 = getFloat();
1168                float f6 = getFloat();
1169                int32_t i1 = getInt();
1170                SkPaint* paint = getPaint(renderer);
1171                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
1172                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
1173                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
1174            }
1175            break;
1176            case DrawPath: {
1177                SkPath* path = getPath();
1178                SkPaint* paint = getPaint(renderer);
1179                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
1180                drawGlStatus |= renderer.drawPath(path, paint);
1181            }
1182            break;
1183            case DrawLines: {
1184                int32_t count = 0;
1185                float* points = getFloats(count);
1186                SkPaint* paint = getPaint(renderer);
1187                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1188                drawGlStatus |= renderer.drawLines(points, count, paint);
1189            }
1190            break;
1191            case DrawPoints: {
1192                int32_t count = 0;
1193                float* points = getFloats(count);
1194                SkPaint* paint = getPaint(renderer);
1195                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1196                drawGlStatus |= renderer.drawPoints(points, count, paint);
1197            }
1198            break;
1199            case DrawText: {
1200                getText(&text);
1201                int32_t count = getInt();
1202                float x = getFloat();
1203                float y = getFloat();
1204                SkPaint* paint = getPaint(renderer);
1205                float length = getFloat();
1206                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
1207                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
1208                drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y,
1209                        paint, length);
1210            }
1211            break;
1212            case DrawTextOnPath: {
1213                getText(&text);
1214                int32_t count = getInt();
1215                SkPath* path = getPath();
1216                float hOffset = getFloat();
1217                float vOffset = getFloat();
1218                SkPaint* paint = getPaint(renderer);
1219                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
1220                    text.text(), text.length(), count, paint);
1221                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
1222                        hOffset, vOffset, paint);
1223            }
1224            break;
1225            case DrawPosText: {
1226                getText(&text);
1227                int32_t count = getInt();
1228                int32_t positionsCount = 0;
1229                float* positions = getFloats(positionsCount);
1230                SkPaint* paint = getPaint(renderer);
1231                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
1232                        OP_NAMES[op], text.text(), text.length(), count, paint);
1233                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
1234                        positions, paint);
1235            }
1236            break;
1237            case ResetShader: {
1238                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1239                renderer.resetShader();
1240            }
1241            break;
1242            case SetupShader: {
1243                SkiaShader* shader = getShader();
1244                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
1245                renderer.setupShader(shader);
1246            }
1247            break;
1248            case ResetColorFilter: {
1249                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1250                renderer.resetColorFilter();
1251            }
1252            break;
1253            case SetupColorFilter: {
1254                SkiaColorFilter *colorFilter = getColorFilter();
1255                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
1256                renderer.setupColorFilter(colorFilter);
1257            }
1258            break;
1259            case ResetShadow: {
1260                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1261                renderer.resetShadow();
1262            }
1263            break;
1264            case SetupShadow: {
1265                float radius = getFloat();
1266                float dx = getFloat();
1267                float dy = getFloat();
1268                int32_t color = getInt();
1269                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
1270                        radius, dx, dy, color);
1271                renderer.setupShadow(radius, dx, dy, color);
1272            }
1273            break;
1274            case ResetPaintFilter: {
1275                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1276                renderer.resetPaintFilter();
1277            }
1278            break;
1279            case SetupPaintFilter: {
1280                int32_t clearBits = getInt();
1281                int32_t setBits = getInt();
1282                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
1283                        clearBits, setBits);
1284                renderer.setupPaintFilter(clearBits, setBits);
1285            }
1286            break;
1287            default:
1288                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
1289                        (char*) indent, OP_NAMES[op]);
1290                break;
1291        }
1292    }
1293
1294    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
1295    renderer.restoreToCount(restoreTo);
1296    renderer.endMark();
1297
1298    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
1299            drawGlStatus);
1300    return drawGlStatus;
1301}
1302
1303///////////////////////////////////////////////////////////////////////////////
1304// Base structure
1305///////////////////////////////////////////////////////////////////////////////
1306
1307DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
1308        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
1309}
1310
1311DisplayListRenderer::~DisplayListRenderer() {
1312    reset();
1313}
1314
1315void DisplayListRenderer::reset() {
1316    mWriter.reset();
1317
1318    Caches& caches = Caches::getInstance();
1319    for (size_t i = 0; i < mBitmapResources.size(); i++) {
1320        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
1321    }
1322    mBitmapResources.clear();
1323
1324    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
1325        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
1326        caches.resourceCache.decrementRefcount(bitmap);
1327    }
1328    mOwnedBitmapResources.clear();
1329
1330    for (size_t i = 0; i < mFilterResources.size(); i++) {
1331        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
1332    }
1333    mFilterResources.clear();
1334
1335    for (size_t i = 0; i < mShaders.size(); i++) {
1336        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
1337    }
1338    mShaders.clear();
1339    mShaderMap.clear();
1340
1341    for (size_t i = 0; i < mSourcePaths.size(); i++) {
1342        caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
1343    }
1344    mSourcePaths.clear();
1345
1346    mPaints.clear();
1347    mPaintMap.clear();
1348
1349    mPaths.clear();
1350    mPathMap.clear();
1351
1352    mMatrices.clear();
1353
1354    mHasDrawOps = false;
1355}
1356
1357///////////////////////////////////////////////////////////////////////////////
1358// Operations
1359///////////////////////////////////////////////////////////////////////////////
1360
1361DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
1362    if (!displayList) {
1363        displayList = new DisplayList(*this);
1364    } else {
1365        displayList->initFromDisplayListRenderer(*this, true);
1366    }
1367    displayList->setRenderable(mHasDrawOps);
1368    return displayList;
1369}
1370
1371bool DisplayListRenderer::isDeferred() {
1372    return true;
1373}
1374
1375void DisplayListRenderer::setViewport(int width, int height) {
1376    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1377
1378    mWidth = width;
1379    mHeight = height;
1380}
1381
1382int DisplayListRenderer::prepareDirty(float left, float top,
1383        float right, float bottom, bool opaque) {
1384    mSnapshot = new Snapshot(mFirstSnapshot,
1385            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1386    mSaveCount = 1;
1387    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1388    mRestoreSaveCount = -1;
1389    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1390}
1391
1392void DisplayListRenderer::finish() {
1393    insertRestoreToCount();
1394    insertTranlate();
1395}
1396
1397void DisplayListRenderer::interrupt() {
1398}
1399
1400void DisplayListRenderer::resume() {
1401}
1402
1403status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1404    // Ignore dirty during recording, it matters only when we replay
1405    addOp(DisplayList::DrawGLFunction);
1406    addInt((int) functor);
1407    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1408}
1409
1410int DisplayListRenderer::save(int flags) {
1411    addOp(DisplayList::Save);
1412    addInt(flags);
1413    return OpenGLRenderer::save(flags);
1414}
1415
1416void DisplayListRenderer::restore() {
1417    if (mRestoreSaveCount < 0) {
1418        restoreToCount(getSaveCount() - 1);
1419        return;
1420    }
1421
1422    mRestoreSaveCount--;
1423    insertTranlate();
1424    OpenGLRenderer::restore();
1425}
1426
1427void DisplayListRenderer::restoreToCount(int saveCount) {
1428    mRestoreSaveCount = saveCount;
1429    insertTranlate();
1430    OpenGLRenderer::restoreToCount(saveCount);
1431}
1432
1433int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1434        SkPaint* p, int flags) {
1435    addOp(DisplayList::SaveLayer);
1436    addBounds(left, top, right, bottom);
1437    addPaint(p);
1438    addInt(flags);
1439    return OpenGLRenderer::save(flags);
1440}
1441
1442int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1443        int alpha, int flags) {
1444    addOp(DisplayList::SaveLayerAlpha);
1445    addBounds(left, top, right, bottom);
1446    addInt(alpha);
1447    addInt(flags);
1448    return OpenGLRenderer::save(flags);
1449}
1450
1451void DisplayListRenderer::translate(float dx, float dy) {
1452    mHasTranslate = true;
1453    mTranslateX += dx;
1454    mTranslateY += dy;
1455    insertRestoreToCount();
1456    OpenGLRenderer::translate(dx, dy);
1457}
1458
1459void DisplayListRenderer::rotate(float degrees) {
1460    addOp(DisplayList::Rotate);
1461    addFloat(degrees);
1462    OpenGLRenderer::rotate(degrees);
1463}
1464
1465void DisplayListRenderer::scale(float sx, float sy) {
1466    addOp(DisplayList::Scale);
1467    addPoint(sx, sy);
1468    OpenGLRenderer::scale(sx, sy);
1469}
1470
1471void DisplayListRenderer::skew(float sx, float sy) {
1472    addOp(DisplayList::Skew);
1473    addPoint(sx, sy);
1474    OpenGLRenderer::skew(sx, sy);
1475}
1476
1477void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1478    addOp(DisplayList::SetMatrix);
1479    addMatrix(matrix);
1480    OpenGLRenderer::setMatrix(matrix);
1481}
1482
1483void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1484    addOp(DisplayList::ConcatMatrix);
1485    addMatrix(matrix);
1486    OpenGLRenderer::concatMatrix(matrix);
1487}
1488
1489bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1490        SkRegion::Op op) {
1491    addOp(DisplayList::ClipRect);
1492    addBounds(left, top, right, bottom);
1493    addInt(op);
1494    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1495}
1496
1497status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1498        Rect& dirty, int32_t flags, uint32_t level) {
1499    // dirty is an out parameter and should not be recorded,
1500    // it matters only when replaying the display list
1501
1502    addOp(DisplayList::DrawDisplayList);
1503    addDisplayList(displayList);
1504    addInt(flags);
1505    return DrawGlInfo::kStatusDone;
1506}
1507
1508status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1509    addOp(DisplayList::DrawLayer);
1510    addInt((int) layer);
1511    addPoint(x, y);
1512    addPaint(paint);
1513    return DrawGlInfo::kStatusDone;
1514}
1515
1516status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
1517    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1518    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
1519    addBitmap(bitmap);
1520    addPoint(left, top);
1521    addPaint(paint);
1522    addSkip(location);
1523    return DrawGlInfo::kStatusDone;
1524}
1525
1526status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
1527    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
1528    const mat4 transform(*matrix);
1529    transform.mapRect(r);
1530
1531    const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
1532    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
1533    addBitmap(bitmap);
1534    addMatrix(matrix);
1535    addPaint(paint);
1536    addSkip(location);
1537    return DrawGlInfo::kStatusDone;
1538}
1539
1540status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1541        float srcRight, float srcBottom, float dstLeft, float dstTop,
1542        float dstRight, float dstBottom, SkPaint* paint) {
1543    const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
1544    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
1545    addBitmap(bitmap);
1546    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1547    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1548    addPaint(paint);
1549    addSkip(location);
1550    return DrawGlInfo::kStatusDone;
1551}
1552
1553status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
1554        SkPaint* paint) {
1555    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1556    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
1557    addBitmapData(bitmap);
1558    addPoint(left, top);
1559    addPaint(paint);
1560    addSkip(location);
1561    return DrawGlInfo::kStatusDone;
1562}
1563
1564status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1565        float* vertices, int* colors, SkPaint* paint) {
1566    addOp(DisplayList::DrawBitmapMesh);
1567    addBitmap(bitmap);
1568    addInt(meshWidth);
1569    addInt(meshHeight);
1570    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1571    if (colors) {
1572        addInt(1);
1573        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1574    } else {
1575        addInt(0);
1576    }
1577    addPaint(paint);
1578    return DrawGlInfo::kStatusDone;
1579}
1580
1581status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
1582        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
1583        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
1584    int alpha;
1585    SkXfermode::Mode mode;
1586    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
1587
1588    const bool reject = quickReject(left, top, right, bottom);
1589    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
1590    addBitmap(bitmap);
1591    addInts(xDivs, width);
1592    addInts(yDivs, height);
1593    addUInts(colors, numColors);
1594    addBounds(left, top, right, bottom);
1595    addInt(alpha);
1596    addInt(mode);
1597    addSkip(location);
1598    return DrawGlInfo::kStatusDone;
1599}
1600
1601status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1602    addOp(DisplayList::DrawColor);
1603    addInt(color);
1604    addInt(mode);
1605    return DrawGlInfo::kStatusDone;
1606}
1607
1608status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1609        SkPaint* paint) {
1610    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1611            quickReject(left, top, right, bottom);
1612    uint32_t* location = addOp(DisplayList::DrawRect, reject);
1613    addBounds(left, top, right, bottom);
1614    addPaint(paint);
1615    addSkip(location);
1616    return DrawGlInfo::kStatusDone;
1617}
1618
1619status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1620        float rx, float ry, SkPaint* paint) {
1621    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1622            quickReject(left, top, right, bottom);
1623    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
1624    addBounds(left, top, right, bottom);
1625    addPoint(rx, ry);
1626    addPaint(paint);
1627    addSkip(location);
1628    return DrawGlInfo::kStatusDone;
1629}
1630
1631status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1632    addOp(DisplayList::DrawCircle);
1633    addPoint(x, y);
1634    addFloat(radius);
1635    addPaint(paint);
1636    return DrawGlInfo::kStatusDone;
1637}
1638
1639status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1640        SkPaint* paint) {
1641    addOp(DisplayList::DrawOval);
1642    addBounds(left, top, right, bottom);
1643    addPaint(paint);
1644    return DrawGlInfo::kStatusDone;
1645}
1646
1647status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1648        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1649    addOp(DisplayList::DrawArc);
1650    addBounds(left, top, right, bottom);
1651    addPoint(startAngle, sweepAngle);
1652    addInt(useCenter ? 1 : 0);
1653    addPaint(paint);
1654    return DrawGlInfo::kStatusDone;
1655}
1656
1657status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1658    float left, top, offset;
1659    uint32_t width, height;
1660    computePathBounds(path, paint, left, top, offset, width, height);
1661
1662    left -= offset;
1663    top -= offset;
1664
1665    const bool reject = quickReject(left, top, left + width, top + height);
1666    uint32_t* location = addOp(DisplayList::DrawPath, reject);
1667    addPath(path);
1668    addPaint(paint);
1669    addSkip(location);
1670    return DrawGlInfo::kStatusDone;
1671}
1672
1673status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1674    addOp(DisplayList::DrawLines);
1675    addFloats(points, count);
1676    addPaint(paint);
1677    return DrawGlInfo::kStatusDone;
1678}
1679
1680status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1681    addOp(DisplayList::DrawPoints);
1682    addFloats(points, count);
1683    addPaint(paint);
1684    return DrawGlInfo::kStatusDone;
1685}
1686
1687status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1688        float x, float y, SkPaint* paint, float length) {
1689    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1690
1691    // TODO: We should probably make a copy of the paint instead of modifying
1692    //       it; modifying the paint will change its generationID the first
1693    //       time, which might impact caches. More investigation needed to
1694    //       see if it matters.
1695    //       If we make a copy, then drawTextDecorations() should *not* make
1696    //       its own copy as it does right now.
1697    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1698    paint->setAntiAlias(true);
1699    if (length < 0.0f) length = paint->measureText(text, bytesCount);
1700
1701    bool reject = false;
1702    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
1703        SkPaint::FontMetrics metrics;
1704        paint->getFontMetrics(&metrics, 0.0f);
1705        reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
1706    }
1707
1708    uint32_t* location = addOp(DisplayList::DrawText, reject);
1709    addText(text, bytesCount);
1710    addInt(count);
1711    addPoint(x, y);
1712    addPaint(paint);
1713    addFloat(length);
1714    addSkip(location);
1715    return DrawGlInfo::kStatusDone;
1716}
1717
1718status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
1719        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
1720    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1721    addOp(DisplayList::DrawTextOnPath);
1722    addText(text, bytesCount);
1723    addInt(count);
1724    addPath(path);
1725    addFloat(hOffset);
1726    addFloat(vOffset);
1727    paint->setAntiAlias(true);
1728    addPaint(paint);
1729    return DrawGlInfo::kStatusDone;
1730}
1731
1732status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1733        const float* positions, SkPaint* paint) {
1734    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1735    addOp(DisplayList::DrawPosText);
1736    addText(text, bytesCount);
1737    addInt(count);
1738    addFloats(positions, count * 2);
1739    paint->setAntiAlias(true);
1740    addPaint(paint);
1741    return DrawGlInfo::kStatusDone;
1742}
1743
1744void DisplayListRenderer::resetShader() {
1745    addOp(DisplayList::ResetShader);
1746}
1747
1748void DisplayListRenderer::setupShader(SkiaShader* shader) {
1749    addOp(DisplayList::SetupShader);
1750    addShader(shader);
1751}
1752
1753void DisplayListRenderer::resetColorFilter() {
1754    addOp(DisplayList::ResetColorFilter);
1755}
1756
1757void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1758    addOp(DisplayList::SetupColorFilter);
1759    addColorFilter(filter);
1760}
1761
1762void DisplayListRenderer::resetShadow() {
1763    addOp(DisplayList::ResetShadow);
1764}
1765
1766void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1767    addOp(DisplayList::SetupShadow);
1768    addFloat(radius);
1769    addPoint(dx, dy);
1770    addInt(color);
1771}
1772
1773void DisplayListRenderer::resetPaintFilter() {
1774    addOp(DisplayList::ResetPaintFilter);
1775}
1776
1777void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1778    addOp(DisplayList::SetupPaintFilter);
1779    addInt(clearBits);
1780    addInt(setBits);
1781}
1782
1783}; // namespace uirenderer
1784}; // namespace android
1785