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