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