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