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