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