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