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