DisplayListRenderer.cpp revision 8b2f5267f16c295f12faab810527cd6311997e34
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OpenGLRenderer"
18
19#include "DisplayListRenderer.h"
20
21namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Defines
26///////////////////////////////////////////////////////////////////////////////
27
28#define PATH_HEAP_SIZE 64
29
30///////////////////////////////////////////////////////////////////////////////
31// Helpers
32///////////////////////////////////////////////////////////////////////////////
33
34PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
35}
36
37PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
38    int count = buffer.readS32();
39
40    mPaths.setCount(count);
41    SkPath** ptr = mPaths.begin();
42    SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath));
43
44    for (int i = 0; i < count; i++) {
45        new (p) SkPath;
46        p->unflatten(buffer);
47        *ptr++ = p;
48        p++;
49    }
50}
51
52PathHeap::~PathHeap() {
53    SkPath** iter = mPaths.begin();
54    SkPath** stop = mPaths.end();
55    while (iter < stop) {
56        (*iter)->~SkPath();
57        iter++;
58    }
59}
60
61int PathHeap::append(const SkPath& path) {
62    SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath));
63    new (p) SkPath(path);
64    *mPaths.append() = p;
65    return mPaths.count();
66}
67
68void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const {
69    int count = mPaths.count();
70
71    buffer.write32(count);
72    SkPath** iter = mPaths.begin();
73    SkPath** stop = mPaths.end();
74    while (iter < stop) {
75        (*iter)->flatten(buffer);
76        iter++;
77    }
78}
79
80///////////////////////////////////////////////////////////////////////////////
81// Display list
82///////////////////////////////////////////////////////////////////////////////
83
84const char* DisplayList::OP_NAMES[] = {
85    "AcquireContext",
86    "ReleaseContext",
87    "Save",
88    "Restore",
89    "RestoreToCount",
90    "SaveLayer",
91    "SaveLayerAlpha",
92    "Translate",
93    "Rotate",
94    "Scale",
95    "Skew",
96    "SetMatrix",
97    "ConcatMatrix",
98    "ClipRect",
99    "DrawDisplayList",
100    "DrawLayer",
101    "DrawBitmap",
102    "DrawBitmapMatrix",
103    "DrawBitmapRect",
104    "DrawBitmapMesh",
105    "DrawPatch",
106    "DrawColor",
107    "DrawRect",
108    "DrawRoundRect",
109    "DrawCircle",
110    "DrawOval",
111    "DrawArc",
112    "DrawPath",
113    "DrawLines",
114    "DrawText",
115    "ResetShader",
116    "SetupShader",
117    "ResetColorFilter",
118    "SetupColorFilter",
119    "ResetShadow",
120    "SetupShadow"
121};
122
123DisplayList::DisplayList(const DisplayListRenderer& recorder) {
124    initFromDisplayListRenderer(recorder);
125}
126
127DisplayList::~DisplayList() {
128    sk_free((void*) mReader.base());
129
130    Caches& caches = Caches::getInstance();
131
132    for (size_t i = 0; i < mBitmapResources.size(); i++) {
133        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
134    }
135    mBitmapResources.clear();
136
137    for (size_t i = 0; i < mShaders.size(); i++) {
138        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
139    }
140    mShaders.clear();
141
142    for (size_t i = 0; i < mPaints.size(); i++) {
143        delete mPaints.itemAt(i);
144    }
145    mPaints.clear();
146
147    for (size_t i = 0; i < mMatrices.size(); i++) {
148        delete mMatrices.itemAt(i);
149    }
150    mMatrices.clear();
151
152    if (mPathHeap) {
153        for (int i = 0; i < mPathHeap->count(); i++) {
154            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
155        }
156        mPathHeap->safeUnref();
157    }
158}
159
160void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
161    const SkWriter32& writer = recorder.writeStream();
162    init();
163
164    if (writer.size() == 0) {
165        return;
166    }
167
168    size_t size = writer.size();
169    void* buffer = sk_malloc_throw(size);
170    writer.flatten(buffer);
171    mReader.setMemory(buffer, size);
172
173    mRCPlayback.reset(&recorder.mRCRecorder);
174    mRCPlayback.setupBuffer(mReader);
175
176    mTFPlayback.reset(&recorder.mTFRecorder);
177    mTFPlayback.setupBuffer(mReader);
178
179    Caches& caches = Caches::getInstance();
180
181    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
182    for (size_t i = 0; i < bitmapResources.size(); i++) {
183        SkBitmap* resource = bitmapResources.itemAt(i);
184        mBitmapResources.add(resource);
185        caches.resourceCache.incrementRefcount(resource);
186    }
187
188    const Vector<SkiaShader*> &shaders = recorder.getShaders();
189    for (size_t i = 0; i < shaders.size(); i++) {
190        SkiaShader* shader = shaders.itemAt(i);
191        mShaders.add(shader);
192        caches.resourceCache.incrementRefcount(shader);
193    }
194
195    const Vector<SkPaint*> &paints = recorder.getPaints();
196    for (size_t i = 0; i < paints.size(); i++) {
197        mPaints.add(paints.itemAt(i));
198    }
199
200    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
201    for (size_t i = 0; i < matrices.size(); i++) {
202        mMatrices.add(matrices.itemAt(i));
203    }
204
205    mPathHeap = recorder.mPathHeap;
206    if (mPathHeap) {
207        mPathHeap->safeRef();
208    }
209}
210
211void DisplayList::init() {
212    mPathHeap = NULL;
213}
214
215void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
216    TextContainer text;
217    mReader.rewind();
218
219#if DEBUG_DISPLAY_LIST
220    uint32_t count = (level + 1) * 2;
221    char indent[count + 1];
222    for (uint32_t i = 0; i < count; i++) {
223        indent[i] = ' ';
224    }
225    indent[count] = '\0';
226    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
227#endif
228
229    int saveCount = renderer.getSaveCount() - 1;
230    while (!mReader.eof()) {
231        int op = mReader.readInt();
232        DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
233
234        switch (op) {
235            case AcquireContext: {
236                renderer.acquireContext();
237            }
238            break;
239            case ReleaseContext: {
240                renderer.releaseContext();
241            }
242            break;
243            case Save: {
244                renderer.save(getInt());
245            }
246            break;
247            case Restore: {
248                renderer.restore();
249            }
250            break;
251            case RestoreToCount: {
252                renderer.restoreToCount(saveCount + getInt());
253            }
254            break;
255            case SaveLayer: {
256                renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
257                        getPaint(), getInt());
258            }
259            break;
260            case SaveLayerAlpha: {
261                renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
262                        getInt(), getInt());
263            }
264            break;
265            case Translate: {
266                renderer.translate(getFloat(), getFloat());
267            }
268            break;
269            case Rotate: {
270                renderer.rotate(getFloat());
271            }
272            break;
273            case Scale: {
274                renderer.scale(getFloat(), getFloat());
275            }
276            break;
277            case Skew: {
278                renderer.skew(getFloat(), getFloat());
279            }
280            break;
281            case SetMatrix: {
282                renderer.setMatrix(getMatrix());
283            }
284            break;
285            case ConcatMatrix: {
286                renderer.concatMatrix(getMatrix());
287            }
288            break;
289            case ClipRect: {
290                renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
291                        (SkRegion::Op) getInt());
292            }
293            break;
294            case DrawDisplayList: {
295                renderer.drawDisplayList(getDisplayList(), level + 1);
296            }
297            break;
298            case DrawLayer: {
299                renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint());
300            }
301            break;
302            case DrawBitmap: {
303                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
304            }
305            break;
306            case DrawBitmapMatrix: {
307                renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
308            }
309            break;
310            case DrawBitmapRect: {
311                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
312                        getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
313            }
314            break;
315            case DrawBitmapMesh: {
316                int verticesCount = 0;
317                uint32_t colorsCount = 0;
318
319                SkBitmap* bitmap = getBitmap();
320                uint32_t meshWidth = getInt();
321                uint32_t meshHeight = getInt();
322                float* vertices = getFloats(verticesCount);
323                bool hasColors = getInt();
324                int* colors = hasColors ? getInts(colorsCount) : NULL;
325
326                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
327            }
328            case DrawPatch: {
329                int32_t* xDivs = NULL;
330                int32_t* yDivs = NULL;
331                uint32_t* colors = NULL;
332                uint32_t xDivsCount = 0;
333                uint32_t yDivsCount = 0;
334                int8_t numColors = 0;
335
336                SkBitmap* bitmap = getBitmap();
337
338                xDivs = getInts(xDivsCount);
339                yDivs = getInts(yDivsCount);
340                colors = getUInts(numColors);
341
342                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
343                        numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
344            }
345            break;
346            case DrawColor: {
347                renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
348            }
349            break;
350            case DrawRect: {
351                renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
352            }
353            break;
354            case DrawRoundRect: {
355                renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
356                        getFloat(), getFloat(), getPaint());
357            }
358            break;
359            case DrawCircle: {
360                renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
361            }
362            break;
363            case DrawOval: {
364                renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
365            }
366            break;
367            case DrawArc: {
368                renderer.drawArc(getFloat(), getFloat(), getFloat(), getFloat(),
369                        getFloat(), getFloat(), getInt() == 1, getPaint());
370            }
371            break;
372            case DrawPath: {
373                renderer.drawPath(getPath(), getPaint());
374            }
375            break;
376            case DrawLines: {
377                int count = 0;
378                float* points = getFloats(count);
379                renderer.drawLines(points, count, getPaint());
380            }
381            break;
382            case DrawText: {
383                getText(&text);
384                renderer.drawText(text.text(), text.length(), getInt(),
385                        getFloat(), getFloat(), getPaint());
386            }
387            break;
388            case ResetShader: {
389                renderer.resetShader();
390            }
391            break;
392            case SetupShader: {
393                renderer.setupShader(getShader());
394            }
395            break;
396            case ResetColorFilter: {
397                renderer.resetColorFilter();
398            }
399            break;
400            case SetupColorFilter: {
401                renderer.setupColorFilter(getColorFilter());
402            }
403            break;
404            case ResetShadow: {
405                renderer.resetShadow();
406            }
407            break;
408            case SetupShadow: {
409                renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
410            }
411            break;
412        }
413    }
414
415    DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2);
416}
417
418///////////////////////////////////////////////////////////////////////////////
419// Base structure
420///////////////////////////////////////////////////////////////////////////////
421
422DisplayListRenderer::DisplayListRenderer():
423        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
424    mPathHeap = NULL;
425    mDisplayList = NULL;
426}
427
428DisplayListRenderer::~DisplayListRenderer() {
429    reset();
430}
431
432void DisplayListRenderer::reset() {
433    if (mPathHeap) {
434        mPathHeap->unref();
435        mPathHeap = NULL;
436    }
437
438    mWriter.reset();
439    mHeap.reset();
440
441    mRCRecorder.reset();
442    mTFRecorder.reset();
443
444    Caches& caches = Caches::getInstance();
445    for (size_t i = 0; i < mBitmapResources.size(); i++) {
446        SkBitmap* resource = mBitmapResources.itemAt(i);
447        caches.resourceCache.decrementRefcount(resource);
448    }
449    mBitmapResources.clear();
450
451    for (size_t i = 0; i < mShaders.size(); i++) {
452       caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
453    }
454    mShaders.clear();
455    mShaderMap.clear();
456
457    mPaints.clear();
458    mPaintMap.clear();
459    mMatrices.clear();
460}
461
462///////////////////////////////////////////////////////////////////////////////
463// Operations
464///////////////////////////////////////////////////////////////////////////////
465
466DisplayList* DisplayListRenderer::getDisplayList() {
467    if (mDisplayList == NULL) {
468        mDisplayList = new DisplayList(*this);
469    } else {
470        mDisplayList->initFromDisplayListRenderer(*this);
471    }
472    return mDisplayList;
473}
474
475void DisplayListRenderer::setViewport(int width, int height) {
476    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
477
478    mWidth = width;
479    mHeight = height;
480}
481
482void DisplayListRenderer::prepare(bool opaque) {
483    mSnapshot = new Snapshot(mFirstSnapshot,
484            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
485    mSaveCount = 1;
486    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
487    mRestoreSaveCount = -1;
488}
489
490void DisplayListRenderer::finish() {
491    insertRestoreToCount();
492    OpenGLRenderer::finish();
493}
494
495void DisplayListRenderer::acquireContext() {
496    addOp(DisplayList::AcquireContext);
497    OpenGLRenderer::acquireContext();
498}
499
500void DisplayListRenderer::releaseContext() {
501    addOp(DisplayList::ReleaseContext);
502    OpenGLRenderer::releaseContext();
503}
504
505int DisplayListRenderer::save(int flags) {
506    addOp(DisplayList::Save);
507    addInt(flags);
508    return OpenGLRenderer::save(flags);
509}
510
511void DisplayListRenderer::restore() {
512    addOp(DisplayList::Restore);
513    OpenGLRenderer::restore();
514}
515
516void DisplayListRenderer::restoreToCount(int saveCount) {
517    mRestoreSaveCount = saveCount;
518    OpenGLRenderer::restoreToCount(saveCount);
519}
520
521int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
522        SkPaint* p, int flags) {
523    addOp(DisplayList::SaveLayer);
524    addBounds(left, top, right, bottom);
525    addPaint(p);
526    addInt(flags);
527    return OpenGLRenderer::save(flags);
528}
529
530int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
531        int alpha, int flags) {
532    addOp(DisplayList::SaveLayerAlpha);
533    addBounds(left, top, right, bottom);
534    addInt(alpha);
535    addInt(flags);
536    return OpenGLRenderer::save(flags);
537}
538
539void DisplayListRenderer::translate(float dx, float dy) {
540    addOp(DisplayList::Translate);
541    addPoint(dx, dy);
542    OpenGLRenderer::translate(dx, dy);
543}
544
545void DisplayListRenderer::rotate(float degrees) {
546    addOp(DisplayList::Rotate);
547    addFloat(degrees);
548    OpenGLRenderer::rotate(degrees);
549}
550
551void DisplayListRenderer::scale(float sx, float sy) {
552    addOp(DisplayList::Scale);
553    addPoint(sx, sy);
554    OpenGLRenderer::scale(sx, sy);
555}
556
557void DisplayListRenderer::skew(float sx, float sy) {
558    addOp(DisplayList::Skew);
559    addPoint(sx, sy);
560    OpenGLRenderer::skew(sx, sy);
561}
562
563void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
564    addOp(DisplayList::SetMatrix);
565    addMatrix(matrix);
566    OpenGLRenderer::setMatrix(matrix);
567}
568
569void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
570    addOp(DisplayList::ConcatMatrix);
571    addMatrix(matrix);
572    OpenGLRenderer::concatMatrix(matrix);
573}
574
575bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
576        SkRegion::Op op) {
577    addOp(DisplayList::ClipRect);
578    addBounds(left, top, right, bottom);
579    addInt(op);
580    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
581}
582
583void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
584    addOp(DisplayList::DrawDisplayList);
585    addDisplayList(displayList);
586}
587
588void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
589    addOp(DisplayList::DrawLayer);
590    addInt((int) layer);
591    addPoint(x, y);
592    addPaint(paint);
593}
594
595void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
596        SkPaint* paint) {
597    addOp(DisplayList::DrawBitmap);
598    addBitmap(bitmap);
599    addPoint(left, top);
600    addPaint(paint);
601}
602
603void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
604        SkPaint* paint) {
605    addOp(DisplayList::DrawBitmapMatrix);
606    addBitmap(bitmap);
607    addMatrix(matrix);
608    addPaint(paint);
609}
610
611void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
612        float srcRight, float srcBottom, float dstLeft, float dstTop,
613        float dstRight, float dstBottom, SkPaint* paint) {
614    addOp(DisplayList::DrawBitmapRect);
615    addBitmap(bitmap);
616    addBounds(srcLeft, srcTop, srcRight, srcBottom);
617    addBounds(dstLeft, dstTop, dstRight, dstBottom);
618    addPaint(paint);
619}
620
621void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
622        float* vertices, int* colors, SkPaint* paint) {
623    addOp(DisplayList::DrawBitmapMesh);
624    addBitmap(bitmap);
625    addInt(meshWidth);
626    addInt(meshHeight);
627    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
628    if (colors) {
629        addInt(1);
630        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
631    } else {
632        addInt(0);
633    }
634    addPaint(paint);
635}
636
637void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
638        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
639        float left, float top, float right, float bottom, SkPaint* paint) {
640    addOp(DisplayList::DrawPatch);
641    addBitmap(bitmap);
642    addInts(xDivs, width);
643    addInts(yDivs, height);
644    addUInts(colors, numColors);
645    addBounds(left, top, right, bottom);
646    addPaint(paint);
647}
648
649void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
650    addOp(DisplayList::DrawColor);
651    addInt(color);
652    addInt(mode);
653}
654
655void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
656        SkPaint* paint) {
657    addOp(DisplayList::DrawRect);
658    addBounds(left, top, right, bottom);
659    addPaint(paint);
660}
661
662void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
663            float rx, float ry, SkPaint* paint) {
664    addOp(DisplayList::DrawRoundRect);
665    addBounds(left, top, right, bottom);
666    addPoint(rx, ry);
667    addPaint(paint);
668}
669
670void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
671    addOp(DisplayList::DrawCircle);
672    addPoint(x, y);
673    addFloat(radius);
674    addPaint(paint);
675}
676
677void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
678        SkPaint* paint) {
679    addOp(DisplayList::DrawOval);
680    addBounds(left, top, right, bottom);
681    addPaint(paint);
682}
683
684void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
685        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
686    addOp(DisplayList::DrawOval);
687    addBounds(left, top, right, bottom);
688    addPoint(startAngle, sweepAngle);
689    addInt(useCenter ? 1 : 0);
690    addPaint(paint);
691}
692
693void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
694    addOp(DisplayList::DrawPath);
695    addPath(path);
696    addPaint(paint);
697}
698
699void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
700    addOp(DisplayList::DrawLines);
701    addFloats(points, count);
702    addPaint(paint);
703}
704
705void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
706        float x, float y, SkPaint* paint) {
707    addOp(DisplayList::DrawText);
708    addText(text, bytesCount);
709    addInt(count);
710    addPoint(x, y);
711    addPaint(paint);
712}
713
714void DisplayListRenderer::resetShader() {
715    addOp(DisplayList::ResetShader);
716}
717
718void DisplayListRenderer::setupShader(SkiaShader* shader) {
719    addOp(DisplayList::SetupShader);
720    addShader(shader);
721}
722
723void DisplayListRenderer::resetColorFilter() {
724    addOp(DisplayList::ResetColorFilter);
725}
726
727void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
728    addOp(DisplayList::SetupColorFilter);
729    addColorFilter(filter);
730}
731
732void DisplayListRenderer::resetShadow() {
733    addOp(DisplayList::ResetShadow);
734}
735
736void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
737    addOp(DisplayList::SetupShadow);
738    addFloat(radius);
739    addPoint(dx, dy);
740    addInt(color);
741}
742
743}; // namespace uirenderer
744}; // namespace android
745