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