DisplayListRenderer.cpp revision 996e57c84368058be793897ebc355b917a59abc2
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    "DrawTextOnPath",
65    "DrawPosText",
66    "DrawGeneralText",
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 DrawTextOnPath: {
576                getText(&text);
577                int32_t count = getInt();
578                SkPath* path = getPath();
579                float hOffset = getFloat();
580                float vOffset = getFloat();
581                SkPaint* paint = getPaint(renderer);
582                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
583                    text.text(), text.length(), count, paint);
584            }
585            break;
586            case DrawPosText: {
587                getText(&text);
588                int count = getInt();
589                int positionsCount = 0;
590                float* positions = getFloats(positionsCount);
591                SkPaint* paint = getPaint(renderer);
592                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
593                        text.text(), text.length(), count, paint);
594            }
595            break;
596            case DrawGeneralText: {
597                getText(&text);
598                int count = getInt();
599                int positionsCount = 0;
600                float* positions = getFloats(positionsCount);
601                SkPaint* paint = getPaint(renderer);
602                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
603                        text.text(), text.length(), count, paint);
604            }
605            break;
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 DrawTextOnPath: {
1200                getText(&text);
1201                int32_t count = getInt();
1202                SkPath* path = getPath();
1203                float hOffset = getFloat();
1204                float vOffset = getFloat();
1205                SkPaint* paint = getPaint(renderer);
1206                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
1207                    text.text(), text.length(), count, paint);
1208                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
1209                        hOffset, vOffset, paint);
1210            }
1211            break;
1212            case DrawPosText: {
1213                getText(&text);
1214                int32_t count = getInt();
1215                int32_t positionsCount = 0;
1216                float* positions = getFloats(positionsCount);
1217                SkPaint* paint = getPaint(renderer);
1218                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
1219                        OP_NAMES[op], text.text(), text.length(), count, paint);
1220                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
1221                        positions, paint);
1222            }
1223            break;
1224            case DrawGeneralText: {
1225                getText(&text);
1226                int32_t count = getInt();
1227                float x = getFloat();
1228                float y = getFloat();
1229                int32_t positionsCount = 0;
1230                float* positions = getFloats(positionsCount);
1231                SkPaint* paint = getPaint(renderer);
1232                float length = getFloat();
1233                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
1234                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
1235                drawGlStatus |= renderer.drawGeneralText(text.text(), text.length(), count,
1236                        x, y, positions, paint, length);
1237            }
1238            break;
1239            case ResetShader: {
1240                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1241                renderer.resetShader();
1242            }
1243            break;
1244            case SetupShader: {
1245                SkiaShader* shader = getShader();
1246                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
1247                renderer.setupShader(shader);
1248            }
1249            break;
1250            case ResetColorFilter: {
1251                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1252                renderer.resetColorFilter();
1253            }
1254            break;
1255            case SetupColorFilter: {
1256                SkiaColorFilter *colorFilter = getColorFilter();
1257                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
1258                renderer.setupColorFilter(colorFilter);
1259            }
1260            break;
1261            case ResetShadow: {
1262                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1263                renderer.resetShadow();
1264            }
1265            break;
1266            case SetupShadow: {
1267                float radius = getFloat();
1268                float dx = getFloat();
1269                float dy = getFloat();
1270                int32_t color = getInt();
1271                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
1272                        radius, dx, dy, color);
1273                renderer.setupShadow(radius, dx, dy, color);
1274            }
1275            break;
1276            case ResetPaintFilter: {
1277                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1278                renderer.resetPaintFilter();
1279            }
1280            break;
1281            case SetupPaintFilter: {
1282                int32_t clearBits = getInt();
1283                int32_t setBits = getInt();
1284                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
1285                        clearBits, setBits);
1286                renderer.setupPaintFilter(clearBits, setBits);
1287            }
1288            break;
1289            default:
1290                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
1291                        (char*) indent, OP_NAMES[op]);
1292                break;
1293        }
1294    }
1295
1296    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
1297    renderer.restoreToCount(restoreTo);
1298    renderer.endMark();
1299
1300    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
1301            drawGlStatus);
1302    return drawGlStatus;
1303}
1304
1305///////////////////////////////////////////////////////////////////////////////
1306// Base structure
1307///////////////////////////////////////////////////////////////////////////////
1308
1309DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
1310        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
1311}
1312
1313DisplayListRenderer::~DisplayListRenderer() {
1314    reset();
1315}
1316
1317void DisplayListRenderer::reset() {
1318    mWriter.reset();
1319
1320    Caches& caches = Caches::getInstance();
1321    for (size_t i = 0; i < mBitmapResources.size(); i++) {
1322        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
1323    }
1324    mBitmapResources.clear();
1325
1326    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
1327        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
1328        caches.resourceCache.decrementRefcount(bitmap);
1329    }
1330    mOwnedBitmapResources.clear();
1331
1332    for (size_t i = 0; i < mFilterResources.size(); i++) {
1333        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
1334    }
1335    mFilterResources.clear();
1336
1337    for (size_t i = 0; i < mShaders.size(); i++) {
1338        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
1339    }
1340    mShaders.clear();
1341    mShaderMap.clear();
1342
1343    for (size_t i = 0; i < mSourcePaths.size(); i++) {
1344        caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
1345    }
1346    mSourcePaths.clear();
1347
1348    mPaints.clear();
1349    mPaintMap.clear();
1350
1351    mPaths.clear();
1352    mPathMap.clear();
1353
1354    mMatrices.clear();
1355
1356    mHasDrawOps = false;
1357}
1358
1359///////////////////////////////////////////////////////////////////////////////
1360// Operations
1361///////////////////////////////////////////////////////////////////////////////
1362
1363DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
1364    if (!displayList) {
1365        displayList = new DisplayList(*this);
1366    } else {
1367        displayList->initFromDisplayListRenderer(*this, true);
1368    }
1369    displayList->setRenderable(mHasDrawOps);
1370    return displayList;
1371}
1372
1373bool DisplayListRenderer::isDeferred() {
1374    return true;
1375}
1376
1377void DisplayListRenderer::setViewport(int width, int height) {
1378    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1379
1380    mWidth = width;
1381    mHeight = height;
1382}
1383
1384int DisplayListRenderer::prepareDirty(float left, float top,
1385        float right, float bottom, bool opaque) {
1386    mSnapshot = new Snapshot(mFirstSnapshot,
1387            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1388    mSaveCount = 1;
1389    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1390    mRestoreSaveCount = -1;
1391    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1392}
1393
1394void DisplayListRenderer::finish() {
1395    insertRestoreToCount();
1396    insertTranlate();
1397}
1398
1399void DisplayListRenderer::interrupt() {
1400}
1401
1402void DisplayListRenderer::resume() {
1403}
1404
1405status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1406    // Ignore dirty during recording, it matters only when we replay
1407    addOp(DisplayList::DrawGLFunction);
1408    addInt((int) functor);
1409    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1410}
1411
1412int DisplayListRenderer::save(int flags) {
1413    addOp(DisplayList::Save);
1414    addInt(flags);
1415    return OpenGLRenderer::save(flags);
1416}
1417
1418void DisplayListRenderer::restore() {
1419    if (mRestoreSaveCount < 0) {
1420        restoreToCount(getSaveCount() - 1);
1421        return;
1422    }
1423
1424    mRestoreSaveCount--;
1425    insertTranlate();
1426    OpenGLRenderer::restore();
1427}
1428
1429void DisplayListRenderer::restoreToCount(int saveCount) {
1430    mRestoreSaveCount = saveCount;
1431    insertTranlate();
1432    OpenGLRenderer::restoreToCount(saveCount);
1433}
1434
1435int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1436        SkPaint* p, int flags) {
1437    addOp(DisplayList::SaveLayer);
1438    addBounds(left, top, right, bottom);
1439    addPaint(p);
1440    addInt(flags);
1441    return OpenGLRenderer::save(flags);
1442}
1443
1444int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1445        int alpha, int flags) {
1446    addOp(DisplayList::SaveLayerAlpha);
1447    addBounds(left, top, right, bottom);
1448    addInt(alpha);
1449    addInt(flags);
1450    return OpenGLRenderer::save(flags);
1451}
1452
1453void DisplayListRenderer::translate(float dx, float dy) {
1454    mHasTranslate = true;
1455    mTranslateX += dx;
1456    mTranslateY += dy;
1457    insertRestoreToCount();
1458    OpenGLRenderer::translate(dx, dy);
1459}
1460
1461void DisplayListRenderer::rotate(float degrees) {
1462    addOp(DisplayList::Rotate);
1463    addFloat(degrees);
1464    OpenGLRenderer::rotate(degrees);
1465}
1466
1467void DisplayListRenderer::scale(float sx, float sy) {
1468    addOp(DisplayList::Scale);
1469    addPoint(sx, sy);
1470    OpenGLRenderer::scale(sx, sy);
1471}
1472
1473void DisplayListRenderer::skew(float sx, float sy) {
1474    addOp(DisplayList::Skew);
1475    addPoint(sx, sy);
1476    OpenGLRenderer::skew(sx, sy);
1477}
1478
1479void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1480    addOp(DisplayList::SetMatrix);
1481    addMatrix(matrix);
1482    OpenGLRenderer::setMatrix(matrix);
1483}
1484
1485void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1486    addOp(DisplayList::ConcatMatrix);
1487    addMatrix(matrix);
1488    OpenGLRenderer::concatMatrix(matrix);
1489}
1490
1491bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1492        SkRegion::Op op) {
1493    addOp(DisplayList::ClipRect);
1494    addBounds(left, top, right, bottom);
1495    addInt(op);
1496    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1497}
1498
1499status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1500        Rect& dirty, int32_t flags, uint32_t level) {
1501    // dirty is an out parameter and should not be recorded,
1502    // it matters only when replaying the display list
1503
1504    addOp(DisplayList::DrawDisplayList);
1505    addDisplayList(displayList);
1506    addInt(flags);
1507    return DrawGlInfo::kStatusDone;
1508}
1509
1510status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1511    addOp(DisplayList::DrawLayer);
1512    addInt((int) layer);
1513    addPoint(x, y);
1514    addPaint(paint);
1515    return DrawGlInfo::kStatusDone;
1516}
1517
1518status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
1519    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1520    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
1521    addBitmap(bitmap);
1522    addPoint(left, top);
1523    addPaint(paint);
1524    addSkip(location);
1525    return DrawGlInfo::kStatusDone;
1526}
1527
1528status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
1529    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
1530    const mat4 transform(*matrix);
1531    transform.mapRect(r);
1532
1533    const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
1534    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
1535    addBitmap(bitmap);
1536    addMatrix(matrix);
1537    addPaint(paint);
1538    addSkip(location);
1539    return DrawGlInfo::kStatusDone;
1540}
1541
1542status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1543        float srcRight, float srcBottom, float dstLeft, float dstTop,
1544        float dstRight, float dstBottom, SkPaint* paint) {
1545    const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
1546    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
1547    addBitmap(bitmap);
1548    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1549    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1550    addPaint(paint);
1551    addSkip(location);
1552    return DrawGlInfo::kStatusDone;
1553}
1554
1555status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
1556        SkPaint* paint) {
1557    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1558    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
1559    addBitmapData(bitmap);
1560    addPoint(left, top);
1561    addPaint(paint);
1562    addSkip(location);
1563    return DrawGlInfo::kStatusDone;
1564}
1565
1566status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1567        float* vertices, int* colors, SkPaint* paint) {
1568    addOp(DisplayList::DrawBitmapMesh);
1569    addBitmap(bitmap);
1570    addInt(meshWidth);
1571    addInt(meshHeight);
1572    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1573    if (colors) {
1574        addInt(1);
1575        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1576    } else {
1577        addInt(0);
1578    }
1579    addPaint(paint);
1580    return DrawGlInfo::kStatusDone;
1581}
1582
1583status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
1584        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
1585        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
1586    int alpha;
1587    SkXfermode::Mode mode;
1588    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
1589
1590    const bool reject = quickReject(left, top, right, bottom);
1591    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
1592    addBitmap(bitmap);
1593    addInts(xDivs, width);
1594    addInts(yDivs, height);
1595    addUInts(colors, numColors);
1596    addBounds(left, top, right, bottom);
1597    addInt(alpha);
1598    addInt(mode);
1599    addSkip(location);
1600    return DrawGlInfo::kStatusDone;
1601}
1602
1603status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1604    addOp(DisplayList::DrawColor);
1605    addInt(color);
1606    addInt(mode);
1607    return DrawGlInfo::kStatusDone;
1608}
1609
1610status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1611        SkPaint* paint) {
1612    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1613            quickReject(left, top, right, bottom);
1614    uint32_t* location = addOp(DisplayList::DrawRect, reject);
1615    addBounds(left, top, right, bottom);
1616    addPaint(paint);
1617    addSkip(location);
1618    return DrawGlInfo::kStatusDone;
1619}
1620
1621status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1622        float rx, float ry, SkPaint* paint) {
1623    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1624            quickReject(left, top, right, bottom);
1625    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
1626    addBounds(left, top, right, bottom);
1627    addPoint(rx, ry);
1628    addPaint(paint);
1629    addSkip(location);
1630    return DrawGlInfo::kStatusDone;
1631}
1632
1633status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1634    addOp(DisplayList::DrawCircle);
1635    addPoint(x, y);
1636    addFloat(radius);
1637    addPaint(paint);
1638    return DrawGlInfo::kStatusDone;
1639}
1640
1641status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1642        SkPaint* paint) {
1643    addOp(DisplayList::DrawOval);
1644    addBounds(left, top, right, bottom);
1645    addPaint(paint);
1646    return DrawGlInfo::kStatusDone;
1647}
1648
1649status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1650        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1651    addOp(DisplayList::DrawArc);
1652    addBounds(left, top, right, bottom);
1653    addPoint(startAngle, sweepAngle);
1654    addInt(useCenter ? 1 : 0);
1655    addPaint(paint);
1656    return DrawGlInfo::kStatusDone;
1657}
1658
1659status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1660    float left, top, offset;
1661    uint32_t width, height;
1662    computePathBounds(path, paint, left, top, offset, width, height);
1663
1664    left -= offset;
1665    top -= offset;
1666
1667    const bool reject = quickReject(left, top, left + width, top + height);
1668    uint32_t* location = addOp(DisplayList::DrawPath, reject);
1669    addPath(path);
1670    addPaint(paint);
1671    addSkip(location);
1672    return DrawGlInfo::kStatusDone;
1673}
1674
1675status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1676    addOp(DisplayList::DrawLines);
1677    addFloats(points, count);
1678    addPaint(paint);
1679    return DrawGlInfo::kStatusDone;
1680}
1681
1682status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1683    addOp(DisplayList::DrawPoints);
1684    addFloats(points, count);
1685    addPaint(paint);
1686    return DrawGlInfo::kStatusDone;
1687}
1688
1689status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
1690        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
1691    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1692    addOp(DisplayList::DrawTextOnPath);
1693    addText(text, bytesCount);
1694    addInt(count);
1695    addPath(path);
1696    addFloat(hOffset);
1697    addFloat(vOffset);
1698    paint->setAntiAlias(true);
1699    addPaint(paint);
1700    return DrawGlInfo::kStatusDone;
1701}
1702
1703status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1704        const float* positions, SkPaint* paint) {
1705    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1706    addOp(DisplayList::DrawPosText);
1707    addText(text, bytesCount);
1708    addInt(count);
1709    addFloats(positions, count * 2);
1710    paint->setAntiAlias(true);
1711    addPaint(paint);
1712    return DrawGlInfo::kStatusDone;
1713}
1714
1715status_t DisplayListRenderer::drawGeneralText(const char* text, int bytesCount, int count,
1716        float x, float y, const float* positions, SkPaint* paint, float length) {
1717    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1718
1719    // TODO: We should probably make a copy of the paint instead of modifying
1720    //       it; modifying the paint will change its generationID the first
1721    //       time, which might impact caches. More investigation needed to
1722    //       see if it matters.
1723    //       If we make a copy, then drawTextDecorations() should *not* make
1724    //       its own copy as it does right now.
1725    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1726    paint->setAntiAlias(true);
1727    if (length < 0.0f) length = paint->measureText(text, bytesCount);
1728
1729    bool reject = false;
1730    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
1731        SkPaint::FontMetrics metrics;
1732        paint->getFontMetrics(&metrics, 0.0f);
1733        reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
1734    }
1735
1736    uint32_t* location = addOp(DisplayList::DrawGeneralText, reject);
1737    addText(text, bytesCount);
1738    addInt(count);
1739    addFloat(x);
1740    addFloat(y);
1741    addFloats(positions, count * 2);
1742    addPaint(paint);
1743    addFloat(length);
1744    addSkip(location);
1745    return DrawGlInfo::kStatusDone;
1746}
1747
1748void DisplayListRenderer::resetShader() {
1749    addOp(DisplayList::ResetShader);
1750}
1751
1752void DisplayListRenderer::setupShader(SkiaShader* shader) {
1753    addOp(DisplayList::SetupShader);
1754    addShader(shader);
1755}
1756
1757void DisplayListRenderer::resetColorFilter() {
1758    addOp(DisplayList::ResetColorFilter);
1759}
1760
1761void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1762    addOp(DisplayList::SetupColorFilter);
1763    addColorFilter(filter);
1764}
1765
1766void DisplayListRenderer::resetShadow() {
1767    addOp(DisplayList::ResetShadow);
1768}
1769
1770void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1771    addOp(DisplayList::SetupShadow);
1772    addFloat(radius);
1773    addPoint(dx, dy);
1774    addInt(color);
1775}
1776
1777void DisplayListRenderer::resetPaintFilter() {
1778    addOp(DisplayList::ResetPaintFilter);
1779}
1780
1781void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1782    addOp(DisplayList::SetupPaintFilter);
1783    addInt(clearBits);
1784    addInt(setBits);
1785}
1786
1787}; // namespace uirenderer
1788}; // namespace android
1789