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