DisplayListRenderer.cpp revision d4a69b4a1cb5b52035345abd8cb9595ae4cf9fa5
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
20#include "DisplayListLogBuffer.h"
21#include "DisplayListRenderer.h"
22#include <utils/String8.h>
23#include "Caches.h"
24
25namespace android {
26namespace uirenderer {
27
28
29///////////////////////////////////////////////////////////////////////////////
30// Display list
31///////////////////////////////////////////////////////////////////////////////
32
33const char* DisplayList::OP_NAMES[] = {
34    "Save",
35    "Restore",
36    "RestoreToCount",
37    "SaveLayer",
38    "SaveLayerAlpha",
39    "Translate",
40    "Rotate",
41    "Scale",
42    "Skew",
43    "SetMatrix",
44    "ConcatMatrix",
45    "ClipRect",
46    "DrawDisplayList",
47    "DrawLayer",
48    "DrawBitmap",
49    "DrawBitmapMatrix",
50    "DrawBitmapRect",
51    "DrawBitmapMesh",
52    "DrawPatch",
53    "DrawColor",
54    "DrawRect",
55    "DrawRoundRect",
56    "DrawCircle",
57    "DrawOval",
58    "DrawArc",
59    "DrawPath",
60    "DrawLines",
61    "DrawPoints",
62    "DrawText",
63    "ResetShader",
64    "SetupShader",
65    "ResetColorFilter",
66    "SetupColorFilter",
67    "ResetShadow",
68    "SetupShadow",
69    "DrawGLFunction"
70};
71
72void DisplayList::outputLogBuffer(int fd) {
73    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
74    if (logBuffer.isEmpty()) {
75        return;
76    }
77
78    FILE *file = fdopen(fd, "a");
79
80    fprintf(file, "\nRecent DisplayList operations\n");
81    logBuffer.outputCommands(file, OP_NAMES);
82
83    String8 cachesLog;
84    Caches::getInstance().dumpMemoryUsage(cachesLog);
85    fprintf(file, "\nCaches:\n%s", cachesLog.string());
86    fprintf(file, "\n");
87
88    fflush(file);
89}
90
91DisplayList::DisplayList(const DisplayListRenderer& recorder) {
92    initFromDisplayListRenderer(recorder);
93}
94
95DisplayList::~DisplayList() {
96    clearResources();
97}
98
99void DisplayList::clearResources() {
100    sk_free((void*) mReader.base());
101
102    Caches& caches = Caches::getInstance();
103
104    for (size_t i = 0; i < mBitmapResources.size(); i++) {
105        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
106    }
107    mBitmapResources.clear();
108
109    for (size_t i = 0; i < mFilterResources.size(); i++) {
110        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
111    }
112    mFilterResources.clear();
113
114    for (size_t i = 0; i < mShaders.size(); i++) {
115        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
116        caches.resourceCache.destructor(mShaders.itemAt(i));
117    }
118    mShaders.clear();
119
120    for (size_t i = 0; i < mPaints.size(); i++) {
121        delete mPaints.itemAt(i);
122    }
123    mPaints.clear();
124
125    for (size_t i = 0; i < mPaths.size(); i++) {
126        SkPath* path = mPaths.itemAt(i);
127        caches.pathCache.remove(path);
128        delete path;
129    }
130    mPaths.clear();
131
132    for (size_t i = 0; i < mMatrices.size(); i++) {
133        delete mMatrices.itemAt(i);
134    }
135    mMatrices.clear();
136}
137
138void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
139    const SkWriter32& writer = recorder.writeStream();
140    init();
141
142    if (writer.size() == 0) {
143        return;
144    }
145
146    if (reusing) {
147        // re-using display list - clear out previous allocations
148        clearResources();
149    }
150
151    mSize = writer.size();
152    void* buffer = sk_malloc_throw(mSize);
153    writer.flatten(buffer);
154    mReader.setMemory(buffer, mSize);
155
156    Caches& caches = Caches::getInstance();
157
158    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
159    for (size_t i = 0; i < bitmapResources.size(); i++) {
160        SkBitmap* resource = bitmapResources.itemAt(i);
161        mBitmapResources.add(resource);
162        caches.resourceCache.incrementRefcount(resource);
163    }
164
165    const Vector<SkiaColorFilter*> &filterResources = recorder.getFilterResources();
166    for (size_t i = 0; i < filterResources.size(); i++) {
167        SkiaColorFilter* resource = filterResources.itemAt(i);
168        mFilterResources.add(resource);
169        caches.resourceCache.incrementRefcount(resource);
170    }
171
172    const Vector<SkiaShader*> &shaders = recorder.getShaders();
173    for (size_t i = 0; i < shaders.size(); i++) {
174        SkiaShader* resource = shaders.itemAt(i);
175        mShaders.add(resource);
176        caches.resourceCache.incrementRefcount(resource);
177    }
178
179    const Vector<SkPaint*> &paints = recorder.getPaints();
180    for (size_t i = 0; i < paints.size(); i++) {
181        mPaints.add(paints.itemAt(i));
182    }
183
184    const Vector<SkPath*> &paths = recorder.getPaths();
185    for (size_t i = 0; i < paths.size(); i++) {
186        mPaths.add(paths.itemAt(i));
187    }
188
189    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
190    for (size_t i = 0; i < matrices.size(); i++) {
191        mMatrices.add(matrices.itemAt(i));
192    }
193}
194
195void DisplayList::init() {
196    mSize = 0;
197    mIsRenderable = true;
198}
199
200size_t DisplayList::getSize() {
201    return mSize;
202}
203
204/**
205 * This function is a simplified version of replay(), where we simply retrieve and log the
206 * display list. This function should remain in sync with the replay() function.
207 */
208void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
209    TextContainer text;
210
211    uint32_t count = (level + 1) * 2;
212    char indent[count + 1];
213    for (uint32_t i = 0; i < count; i++) {
214        indent[i] = ' ';
215    }
216    indent[count] = '\0';
217    ALOGD("%sStart display list (%p)", (char*) indent + 2, this);
218
219    int saveCount = renderer.getSaveCount() - 1;
220
221    mReader.rewind();
222
223    while (!mReader.eof()) {
224        int op = mReader.readInt();
225
226        switch (op) {
227            case DrawGLFunction: {
228                Functor *functor = (Functor *) getInt();
229                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
230            }
231            break;
232            case Save: {
233                int rendererNum = getInt();
234                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
235            }
236            break;
237            case Restore: {
238                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
239            }
240            break;
241            case RestoreToCount: {
242                int restoreCount = saveCount + getInt();
243                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
244            }
245            break;
246            case SaveLayer: {
247                float f1 = getFloat();
248                float f2 = getFloat();
249                float f3 = getFloat();
250                float f4 = getFloat();
251                SkPaint* paint = getPaint();
252                int flags = getInt();
253                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
254                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
255            }
256            break;
257            case SaveLayerAlpha: {
258                float f1 = getFloat();
259                float f2 = getFloat();
260                float f3 = getFloat();
261                float f4 = getFloat();
262                int alpha = getInt();
263                int flags = getInt();
264                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
265                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
266            }
267            break;
268            case Translate: {
269                float f1 = getFloat();
270                float f2 = getFloat();
271                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
272            }
273            break;
274            case Rotate: {
275                float rotation = getFloat();
276                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
277            }
278            break;
279            case Scale: {
280                float sx = getFloat();
281                float sy = getFloat();
282                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
283            }
284            break;
285            case Skew: {
286                float sx = getFloat();
287                float sy = getFloat();
288                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
289            }
290            break;
291            case SetMatrix: {
292                SkMatrix* matrix = getMatrix();
293                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
294            }
295            break;
296            case ConcatMatrix: {
297                SkMatrix* matrix = getMatrix();
298                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
299            }
300            break;
301            case ClipRect: {
302                float f1 = getFloat();
303                float f2 = getFloat();
304                float f3 = getFloat();
305                float f4 = getFloat();
306                int regionOp = getInt();
307                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
308                    f1, f2, f3, f4, regionOp);
309            }
310            break;
311            case DrawDisplayList: {
312                DisplayList* displayList = getDisplayList();
313                uint32_t width = getUInt();
314                uint32_t height = getUInt();
315                ALOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
316                    displayList, width, height, level + 1);
317                renderer.outputDisplayList(displayList, level + 1);
318            }
319            break;
320            case DrawLayer: {
321                Layer* layer = (Layer*) getInt();
322                float x = getFloat();
323                float y = getFloat();
324                SkPaint* paint = getPaint();
325                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
326                    layer, x, y, paint);
327            }
328            break;
329            case DrawBitmap: {
330                SkBitmap* bitmap = getBitmap();
331                float x = getFloat();
332                float y = getFloat();
333                SkPaint* paint = getPaint();
334                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
335                    bitmap, x, y, paint);
336            }
337            break;
338            case DrawBitmapMatrix: {
339                SkBitmap* bitmap = getBitmap();
340                SkMatrix* matrix = getMatrix();
341                SkPaint* paint = getPaint();
342                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
343                    bitmap, matrix, paint);
344            }
345            break;
346            case DrawBitmapRect: {
347                SkBitmap* bitmap = getBitmap();
348                float f1 = getFloat();
349                float f2 = getFloat();
350                float f3 = getFloat();
351                float f4 = getFloat();
352                float f5 = getFloat();
353                float f6 = getFloat();
354                float f7 = getFloat();
355                float f8 = getFloat();
356                SkPaint* paint = getPaint();
357                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
358                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
359            }
360            break;
361            case DrawBitmapMesh: {
362                int verticesCount = 0;
363                uint32_t colorsCount = 0;
364                SkBitmap* bitmap = getBitmap();
365                uint32_t meshWidth = getInt();
366                uint32_t meshHeight = getInt();
367                float* vertices = getFloats(verticesCount);
368                bool hasColors = getInt();
369                int* colors = hasColors ? getInts(colorsCount) : NULL;
370                SkPaint* paint = getPaint();
371                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
372            }
373            break;
374            case DrawPatch: {
375                int32_t* xDivs = NULL;
376                int32_t* yDivs = NULL;
377                uint32_t* colors = NULL;
378                uint32_t xDivsCount = 0;
379                uint32_t yDivsCount = 0;
380                int8_t numColors = 0;
381                SkBitmap* bitmap = getBitmap();
382                xDivs = getInts(xDivsCount);
383                yDivs = getInts(yDivsCount);
384                colors = getUInts(numColors);
385                float left = getFloat();
386                float top = getFloat();
387                float right = getFloat();
388                float bottom = getFloat();
389                SkPaint* paint = getPaint();
390                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
391                        left, top, right, bottom);
392            }
393            break;
394            case DrawColor: {
395                int color = getInt();
396                int xferMode = getInt();
397                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
398            }
399            break;
400            case DrawRect: {
401                float f1 = getFloat();
402                float f2 = getFloat();
403                float f3 = getFloat();
404                float f4 = getFloat();
405                SkPaint* paint = getPaint();
406                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
407                    f1, f2, f3, f4, paint);
408            }
409            break;
410            case DrawRoundRect: {
411                float f1 = getFloat();
412                float f2 = getFloat();
413                float f3 = getFloat();
414                float f4 = getFloat();
415                float f5 = getFloat();
416                float f6 = getFloat();
417                SkPaint* paint = getPaint();
418                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
419                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
420            }
421            break;
422            case DrawCircle: {
423                float f1 = getFloat();
424                float f2 = getFloat();
425                float f3 = getFloat();
426                SkPaint* paint = getPaint();
427                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
428                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
429            }
430            break;
431            case DrawOval: {
432                float f1 = getFloat();
433                float f2 = getFloat();
434                float f3 = getFloat();
435                float f4 = getFloat();
436                SkPaint* paint = getPaint();
437                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
438                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
439            }
440            break;
441            case DrawArc: {
442                float f1 = getFloat();
443                float f2 = getFloat();
444                float f3 = getFloat();
445                float f4 = getFloat();
446                float f5 = getFloat();
447                float f6 = getFloat();
448                int i1 = getInt();
449                SkPaint* paint = getPaint();
450                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
451                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
452            }
453            break;
454            case DrawPath: {
455                SkPath* path = getPath();
456                SkPaint* paint = getPaint();
457                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
458            }
459            break;
460            case DrawLines: {
461                int count = 0;
462                float* points = getFloats(count);
463                SkPaint* paint = getPaint();
464                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
465            }
466            break;
467            case DrawPoints: {
468                int count = 0;
469                float* points = getFloats(count);
470                SkPaint* paint = getPaint();
471                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
472            }
473            break;
474            case DrawText: {
475                getText(&text);
476                int count = getInt();
477                float x = getFloat();
478                float y = getFloat();
479                SkPaint* paint = getPaint();
480                float length = getFloat();
481                ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
482                    text.text(), text.length(), count, x, y, paint, length);
483            }
484            break;
485            case ResetShader: {
486                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
487            }
488            break;
489            case SetupShader: {
490                SkiaShader* shader = getShader();
491                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
492            }
493            break;
494            case ResetColorFilter: {
495                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
496            }
497            break;
498            case SetupColorFilter: {
499                SkiaColorFilter *colorFilter = getColorFilter();
500                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
501            }
502            break;
503            case ResetShadow: {
504                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
505            }
506            break;
507            case SetupShadow: {
508                float radius = getFloat();
509                float dx = getFloat();
510                float dy = getFloat();
511                int color = getInt();
512                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
513                    radius, dx, dy, color);
514            }
515            break;
516            default:
517                ALOGD("Display List error: op not handled: %s%s",
518                    (char*) indent, OP_NAMES[op]);
519                break;
520        }
521    }
522
523    ALOGD("%sDone", (char*) indent + 2);
524}
525
526/**
527 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
528 * in the output() function, since that function processes the same list of opcodes for the
529 * purposes of logging display list info for a given view.
530 */
531bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
532    bool needsInvalidate = false;
533    TextContainer text;
534    mReader.rewind();
535
536#if DEBUG_DISPLAY_LIST
537    uint32_t count = (level + 1) * 2;
538    char indent[count + 1];
539    for (uint32_t i = 0; i < count; i++) {
540        indent[i] = ' ';
541    }
542    indent[count] = '\0';
543    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
544#endif
545
546    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
547    int saveCount = renderer.getSaveCount() - 1;
548    while (!mReader.eof()) {
549        int op = mReader.readInt();
550        logBuffer.writeCommand(level, op);
551
552        switch (op) {
553            case DrawGLFunction: {
554                Functor *functor = (Functor *) getInt();
555                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
556                needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
557            }
558            break;
559            case Save: {
560                int rendererNum = getInt();
561                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
562                renderer.save(rendererNum);
563            }
564            break;
565            case Restore: {
566                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
567                renderer.restore();
568            }
569            break;
570            case RestoreToCount: {
571                int restoreCount = saveCount + getInt();
572                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
573                renderer.restoreToCount(restoreCount);
574            }
575            break;
576            case SaveLayer: {
577                float f1 = getFloat();
578                float f2 = getFloat();
579                float f3 = getFloat();
580                float f4 = getFloat();
581                SkPaint* paint = getPaint();
582                int flags = getInt();
583                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
584                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
585                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
586            }
587            break;
588            case SaveLayerAlpha: {
589                float f1 = getFloat();
590                float f2 = getFloat();
591                float f3 = getFloat();
592                float f4 = getFloat();
593                int alpha = getInt();
594                int flags = getInt();
595                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
596                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
597                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
598            }
599            break;
600            case Translate: {
601                float f1 = getFloat();
602                float f2 = getFloat();
603                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
604                renderer.translate(f1, f2);
605            }
606            break;
607            case Rotate: {
608                float rotation = getFloat();
609                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
610                renderer.rotate(rotation);
611            }
612            break;
613            case Scale: {
614                float sx = getFloat();
615                float sy = getFloat();
616                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
617                renderer.scale(sx, sy);
618            }
619            break;
620            case Skew: {
621                float sx = getFloat();
622                float sy = getFloat();
623                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
624                renderer.skew(sx, sy);
625            }
626            break;
627            case SetMatrix: {
628                SkMatrix* matrix = getMatrix();
629                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
630                renderer.setMatrix(matrix);
631            }
632            break;
633            case ConcatMatrix: {
634                SkMatrix* matrix = getMatrix();
635                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
636                renderer.concatMatrix(matrix);
637            }
638            break;
639            case ClipRect: {
640                float f1 = getFloat();
641                float f2 = getFloat();
642                float f3 = getFloat();
643                float f4 = getFloat();
644                int regionOp = getInt();
645                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
646                    f1, f2, f3, f4, regionOp);
647                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
648            }
649            break;
650            case DrawDisplayList: {
651                DisplayList* displayList = getDisplayList();
652                uint32_t width = getUInt();
653                uint32_t height = getUInt();
654                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
655                    displayList, width, height, level + 1);
656                needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
657                        dirty, level + 1);
658            }
659            break;
660            case DrawLayer: {
661                Layer* layer = (Layer*) getInt();
662                float x = getFloat();
663                float y = getFloat();
664                SkPaint* paint = getPaint();
665                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
666                    layer, x, y, paint);
667                renderer.drawLayer(layer, x, y, paint);
668            }
669            break;
670            case DrawBitmap: {
671                SkBitmap* bitmap = getBitmap();
672                float x = getFloat();
673                float y = getFloat();
674                SkPaint* paint = getPaint();
675                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
676                    bitmap, x, y, paint);
677                renderer.drawBitmap(bitmap, x, y, paint);
678            }
679            break;
680            case DrawBitmapMatrix: {
681                SkBitmap* bitmap = getBitmap();
682                SkMatrix* matrix = getMatrix();
683                SkPaint* paint = getPaint();
684                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
685                    bitmap, matrix, paint);
686                renderer.drawBitmap(bitmap, matrix, paint);
687            }
688            break;
689            case DrawBitmapRect: {
690                SkBitmap* bitmap = getBitmap();
691                float f1 = getFloat();
692                float f2 = getFloat();
693                float f3 = getFloat();
694                float f4 = getFloat();
695                float f5 = getFloat();
696                float f6 = getFloat();
697                float f7 = getFloat();
698                float f8 = getFloat();
699                SkPaint* paint = getPaint();
700                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
701                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
702                renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
703            }
704            break;
705            case DrawBitmapMesh: {
706                int verticesCount = 0;
707                uint32_t colorsCount = 0;
708
709                SkBitmap* bitmap = getBitmap();
710                uint32_t meshWidth = getInt();
711                uint32_t meshHeight = getInt();
712                float* vertices = getFloats(verticesCount);
713                bool hasColors = getInt();
714                int* colors = hasColors ? getInts(colorsCount) : NULL;
715                SkPaint* paint = getPaint();
716
717                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
718                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
719            }
720            break;
721            case DrawPatch: {
722                int32_t* xDivs = NULL;
723                int32_t* yDivs = NULL;
724                uint32_t* colors = NULL;
725                uint32_t xDivsCount = 0;
726                uint32_t yDivsCount = 0;
727                int8_t numColors = 0;
728
729                SkBitmap* bitmap = getBitmap();
730
731                xDivs = getInts(xDivsCount);
732                yDivs = getInts(yDivsCount);
733                colors = getUInts(numColors);
734
735                float left = getFloat();
736                float top = getFloat();
737                float right = getFloat();
738                float bottom = getFloat();
739                SkPaint* paint = getPaint();
740
741                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
742                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
743                        numColors, left, top, right, bottom, paint);
744            }
745            break;
746            case DrawColor: {
747                int color = getInt();
748                int xferMode = getInt();
749                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
750                renderer.drawColor(color, (SkXfermode::Mode) xferMode);
751            }
752            break;
753            case DrawRect: {
754                float f1 = getFloat();
755                float f2 = getFloat();
756                float f3 = getFloat();
757                float f4 = getFloat();
758                SkPaint* paint = getPaint();
759                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
760                    f1, f2, f3, f4, paint);
761                renderer.drawRect(f1, f2, f3, f4, paint);
762            }
763            break;
764            case DrawRoundRect: {
765                float f1 = getFloat();
766                float f2 = getFloat();
767                float f3 = getFloat();
768                float f4 = getFloat();
769                float f5 = getFloat();
770                float f6 = getFloat();
771                SkPaint* paint = getPaint();
772                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
773                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
774                renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
775            }
776            break;
777            case DrawCircle: {
778                float f1 = getFloat();
779                float f2 = getFloat();
780                float f3 = getFloat();
781                SkPaint* paint = getPaint();
782                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
783                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
784                renderer.drawCircle(f1, f2, f3, paint);
785            }
786            break;
787            case DrawOval: {
788                float f1 = getFloat();
789                float f2 = getFloat();
790                float f3 = getFloat();
791                float f4 = getFloat();
792                SkPaint* paint = getPaint();
793                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
794                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
795                renderer.drawOval(f1, f2, f3, f4, paint);
796            }
797            break;
798            case DrawArc: {
799                float f1 = getFloat();
800                float f2 = getFloat();
801                float f3 = getFloat();
802                float f4 = getFloat();
803                float f5 = getFloat();
804                float f6 = getFloat();
805                int i1 = getInt();
806                SkPaint* paint = getPaint();
807                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
808                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
809                renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
810            }
811            break;
812            case DrawPath: {
813                SkPath* path = getPath();
814                SkPaint* paint = getPaint();
815                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
816                renderer.drawPath(path, paint);
817            }
818            break;
819            case DrawLines: {
820                int count = 0;
821                float* points = getFloats(count);
822                SkPaint* paint = getPaint();
823                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
824                renderer.drawLines(points, count, paint);
825            }
826            break;
827            case DrawPoints: {
828                int count = 0;
829                float* points = getFloats(count);
830                SkPaint* paint = getPaint();
831                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
832                renderer.drawPoints(points, count, paint);
833            }
834            break;
835            case DrawText: {
836                getText(&text);
837                int count = getInt();
838                float x = getFloat();
839                float y = getFloat();
840                SkPaint* paint = getPaint();
841                float length = getFloat();
842                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
843                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
844                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
845            }
846            break;
847            case ResetShader: {
848                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
849                renderer.resetShader();
850            }
851            break;
852            case SetupShader: {
853                SkiaShader* shader = getShader();
854                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
855                renderer.setupShader(shader);
856            }
857            break;
858            case ResetColorFilter: {
859                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
860                renderer.resetColorFilter();
861            }
862            break;
863            case SetupColorFilter: {
864                SkiaColorFilter *colorFilter = getColorFilter();
865                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
866                renderer.setupColorFilter(colorFilter);
867            }
868            break;
869            case ResetShadow: {
870                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
871                renderer.resetShadow();
872            }
873            break;
874            case SetupShadow: {
875                float radius = getFloat();
876                float dx = getFloat();
877                float dy = getFloat();
878                int color = getInt();
879                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
880                    radius, dx, dy, color);
881                renderer.setupShadow(radius, dx, dy, color);
882            }
883            break;
884            default:
885                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
886                    (char*) indent, OP_NAMES[op]);
887                break;
888        }
889    }
890
891    DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
892    return needsInvalidate;
893}
894
895///////////////////////////////////////////////////////////////////////////////
896// Base structure
897///////////////////////////////////////////////////////////////////////////////
898
899DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
900}
901
902DisplayListRenderer::~DisplayListRenderer() {
903    reset();
904}
905
906void DisplayListRenderer::reset() {
907    mWriter.reset();
908
909    Caches& caches = Caches::getInstance();
910    for (size_t i = 0; i < mBitmapResources.size(); i++) {
911        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
912    }
913    mBitmapResources.clear();
914
915    for (size_t i = 0; i < mFilterResources.size(); i++) {
916        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
917    }
918    mFilterResources.clear();
919
920    for (size_t i = 0; i < mShaders.size(); i++) {
921        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
922    }
923    mShaders.clear();
924    mShaderMap.clear();
925
926    mPaints.clear();
927    mPaintMap.clear();
928
929    mPaths.clear();
930    mPathMap.clear();
931
932    mMatrices.clear();
933
934    mHasDrawOps = false;
935}
936
937///////////////////////////////////////////////////////////////////////////////
938// Operations
939///////////////////////////////////////////////////////////////////////////////
940
941DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
942    if (!displayList) {
943        displayList = new DisplayList(*this);
944    } else {
945        displayList->initFromDisplayListRenderer(*this, true);
946    }
947    displayList->setRenderable(mHasDrawOps);
948    return displayList;
949}
950
951void DisplayListRenderer::setViewport(int width, int height) {
952    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
953
954    mWidth = width;
955    mHeight = height;
956}
957
958void DisplayListRenderer::prepareDirty(float left, float top,
959        float right, float bottom, bool opaque) {
960    mSnapshot = new Snapshot(mFirstSnapshot,
961            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
962    mSaveCount = 1;
963    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
964    mRestoreSaveCount = -1;
965}
966
967void DisplayListRenderer::finish() {
968    insertRestoreToCount();
969    OpenGLRenderer::finish();
970}
971
972void DisplayListRenderer::interrupt() {
973}
974
975void DisplayListRenderer::resume() {
976}
977
978bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
979    // Ignore dirty during recording, it matters only when we replay
980    addOp(DisplayList::DrawGLFunction);
981    addInt((int) functor);
982    return false; // No invalidate needed at record-time
983}
984
985int DisplayListRenderer::save(int flags) {
986    addOp(DisplayList::Save);
987    addInt(flags);
988    return OpenGLRenderer::save(flags);
989}
990
991void DisplayListRenderer::restore() {
992    if (mRestoreSaveCount < 0) {
993        addOp(DisplayList::Restore);
994    } else {
995        mRestoreSaveCount--;
996    }
997    OpenGLRenderer::restore();
998}
999
1000void DisplayListRenderer::restoreToCount(int saveCount) {
1001    mRestoreSaveCount = saveCount;
1002    OpenGLRenderer::restoreToCount(saveCount);
1003}
1004
1005int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1006        SkPaint* p, int flags) {
1007    addOp(DisplayList::SaveLayer);
1008    addBounds(left, top, right, bottom);
1009    addPaint(p);
1010    addInt(flags);
1011    return OpenGLRenderer::save(flags);
1012}
1013
1014int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1015        int alpha, int flags) {
1016    addOp(DisplayList::SaveLayerAlpha);
1017    addBounds(left, top, right, bottom);
1018    addInt(alpha);
1019    addInt(flags);
1020    return OpenGLRenderer::save(flags);
1021}
1022
1023void DisplayListRenderer::translate(float dx, float dy) {
1024    addOp(DisplayList::Translate);
1025    addPoint(dx, dy);
1026    OpenGLRenderer::translate(dx, dy);
1027}
1028
1029void DisplayListRenderer::rotate(float degrees) {
1030    addOp(DisplayList::Rotate);
1031    addFloat(degrees);
1032    OpenGLRenderer::rotate(degrees);
1033}
1034
1035void DisplayListRenderer::scale(float sx, float sy) {
1036    addOp(DisplayList::Scale);
1037    addPoint(sx, sy);
1038    OpenGLRenderer::scale(sx, sy);
1039}
1040
1041void DisplayListRenderer::skew(float sx, float sy) {
1042    addOp(DisplayList::Skew);
1043    addPoint(sx, sy);
1044    OpenGLRenderer::skew(sx, sy);
1045}
1046
1047void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1048    addOp(DisplayList::SetMatrix);
1049    addMatrix(matrix);
1050    OpenGLRenderer::setMatrix(matrix);
1051}
1052
1053void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1054    addOp(DisplayList::ConcatMatrix);
1055    addMatrix(matrix);
1056    OpenGLRenderer::concatMatrix(matrix);
1057}
1058
1059bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1060        SkRegion::Op op) {
1061    addOp(DisplayList::ClipRect);
1062    addBounds(left, top, right, bottom);
1063    addInt(op);
1064    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1065}
1066
1067bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1068        uint32_t width, uint32_t height, Rect& dirty, uint32_t level) {
1069    // dirty is an out parameter and should not be recorded,
1070    // it matters only when replaying the display list
1071    addOp(DisplayList::DrawDisplayList);
1072    addDisplayList(displayList);
1073    addSize(width, height);
1074    return false;
1075}
1076
1077void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1078    addOp(DisplayList::DrawLayer);
1079    addInt((int) layer);
1080    addPoint(x, y);
1081    addPaint(paint);
1082}
1083
1084void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
1085        SkPaint* paint) {
1086    addOp(DisplayList::DrawBitmap);
1087    addBitmap(bitmap);
1088    addPoint(left, top);
1089    addPaint(paint);
1090}
1091
1092void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
1093        SkPaint* paint) {
1094    addOp(DisplayList::DrawBitmapMatrix);
1095    addBitmap(bitmap);
1096    addMatrix(matrix);
1097    addPaint(paint);
1098}
1099
1100void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1101        float srcRight, float srcBottom, float dstLeft, float dstTop,
1102        float dstRight, float dstBottom, SkPaint* paint) {
1103    addOp(DisplayList::DrawBitmapRect);
1104    addBitmap(bitmap);
1105    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1106    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1107    addPaint(paint);
1108}
1109
1110void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1111        float* vertices, int* colors, SkPaint* paint) {
1112    addOp(DisplayList::DrawBitmapMesh);
1113    addBitmap(bitmap);
1114    addInt(meshWidth);
1115    addInt(meshHeight);
1116    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1117    if (colors) {
1118        addInt(1);
1119        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1120    } else {
1121        addInt(0);
1122    }
1123    addPaint(paint);
1124}
1125
1126void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
1127        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
1128        float left, float top, float right, float bottom, SkPaint* paint) {
1129    addOp(DisplayList::DrawPatch);
1130    addBitmap(bitmap);
1131    addInts(xDivs, width);
1132    addInts(yDivs, height);
1133    addUInts(colors, numColors);
1134    addBounds(left, top, right, bottom);
1135    addPaint(paint);
1136}
1137
1138void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1139    addOp(DisplayList::DrawColor);
1140    addInt(color);
1141    addInt(mode);
1142}
1143
1144void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1145        SkPaint* paint) {
1146    addOp(DisplayList::DrawRect);
1147    addBounds(left, top, right, bottom);
1148    addPaint(paint);
1149}
1150
1151void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1152            float rx, float ry, SkPaint* paint) {
1153    addOp(DisplayList::DrawRoundRect);
1154    addBounds(left, top, right, bottom);
1155    addPoint(rx, ry);
1156    addPaint(paint);
1157}
1158
1159void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1160    addOp(DisplayList::DrawCircle);
1161    addPoint(x, y);
1162    addFloat(radius);
1163    addPaint(paint);
1164}
1165
1166void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1167        SkPaint* paint) {
1168    addOp(DisplayList::DrawOval);
1169    addBounds(left, top, right, bottom);
1170    addPaint(paint);
1171}
1172
1173void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1174        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1175    addOp(DisplayList::DrawArc);
1176    addBounds(left, top, right, bottom);
1177    addPoint(startAngle, sweepAngle);
1178    addInt(useCenter ? 1 : 0);
1179    addPaint(paint);
1180}
1181
1182void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1183    addOp(DisplayList::DrawPath);
1184    addPath(path);
1185    addPaint(paint);
1186}
1187
1188void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1189    addOp(DisplayList::DrawLines);
1190    addFloats(points, count);
1191    addPaint(paint);
1192}
1193
1194void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1195    addOp(DisplayList::DrawPoints);
1196    addFloats(points, count);
1197    addPaint(paint);
1198}
1199
1200void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1201        float x, float y, SkPaint* paint, float length) {
1202    if (count <= 0) return;
1203    addOp(DisplayList::DrawText);
1204    addText(text, bytesCount);
1205    addInt(count);
1206    addPoint(x, y);
1207    // TODO: We should probably make a copy of the paint instead of modifying
1208    //       it; modifying the paint will change its generationID the first
1209    //       time, which might impact caches. More investigation needed to
1210    //       see if it matters.
1211    //       If we make a copy, then drawTextDecorations() should *not* make
1212    //       its own copy as it does right now.
1213    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1214    paint->setAntiAlias(true);
1215    addPaint(paint);
1216    addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
1217}
1218
1219void DisplayListRenderer::resetShader() {
1220    addOp(DisplayList::ResetShader);
1221}
1222
1223void DisplayListRenderer::setupShader(SkiaShader* shader) {
1224    addOp(DisplayList::SetupShader);
1225    addShader(shader);
1226}
1227
1228void DisplayListRenderer::resetColorFilter() {
1229    addOp(DisplayList::ResetColorFilter);
1230}
1231
1232void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1233    addOp(DisplayList::SetupColorFilter);
1234    addColorFilter(filter);
1235}
1236
1237void DisplayListRenderer::resetShadow() {
1238    addOp(DisplayList::ResetShadow);
1239}
1240
1241void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1242    addOp(DisplayList::SetupShadow);
1243    addFloat(radius);
1244    addPoint(dx, dy);
1245    addInt(color);
1246}
1247
1248}; // namespace uirenderer
1249}; // namespace android
1250