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