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