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