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