DisplayListRenderer.cpp revision 4cf6e2f34994f160e1baba205a43c12784dd3e0d
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    "DrawPath",
111    "DrawLines",
112    "DrawText",
113    "ResetShader",
114    "SetupShader",
115    "ResetColorFilter",
116    "SetupColorFilter",
117    "ResetShadow",
118    "SetupShadow"
119};
120
121DisplayList::DisplayList(const DisplayListRenderer& recorder) {
122    initFromDisplayListRenderer(recorder);
123}
124
125DisplayList::~DisplayList() {
126    sk_free((void*) mReader.base());
127
128    Caches& caches = Caches::getInstance();
129
130    for (size_t i = 0; i < mBitmapResources.size(); i++) {
131        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
132    }
133    mBitmapResources.clear();
134
135    for (size_t i = 0; i < mShaders.size(); i++) {
136        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
137    }
138    mShaders.clear();
139
140    for (size_t i = 0; i < mPaints.size(); i++) {
141        delete mPaints.itemAt(i);
142    }
143    mPaints.clear();
144
145    for (size_t i = 0; i < mMatrices.size(); i++) {
146        delete mMatrices.itemAt(i);
147    }
148    mMatrices.clear();
149
150    if (mPathHeap) {
151        for (int i = 0; i < mPathHeap->count(); i++) {
152            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
153        }
154        mPathHeap->safeUnref();
155    }
156}
157
158void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
159    const SkWriter32& writer = recorder.writeStream();
160    init();
161
162    if (writer.size() == 0) {
163        return;
164    }
165
166    size_t size = writer.size();
167    void* buffer = sk_malloc_throw(size);
168    writer.flatten(buffer);
169    mReader.setMemory(buffer, size);
170
171    mRCPlayback.reset(&recorder.mRCRecorder);
172    mRCPlayback.setupBuffer(mReader);
173
174    mTFPlayback.reset(&recorder.mTFRecorder);
175    mTFPlayback.setupBuffer(mReader);
176
177    Caches& caches = Caches::getInstance();
178
179    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
180    for (size_t i = 0; i < bitmapResources.size(); i++) {
181        SkBitmap* resource = bitmapResources.itemAt(i);
182        mBitmapResources.add(resource);
183        caches.resourceCache.incrementRefcount(resource);
184    }
185
186    const Vector<SkiaShader*> &shaders = recorder.getShaders();
187    for (size_t i = 0; i < shaders.size(); i++) {
188        SkiaShader* shader = shaders.itemAt(i);
189        mShaders.add(shader);
190        caches.resourceCache.incrementRefcount(shader);
191    }
192
193    const Vector<SkPaint*> &paints = recorder.getPaints();
194    for (size_t i = 0; i < paints.size(); i++) {
195        mPaints.add(paints.itemAt(i));
196    }
197
198    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
199    for (size_t i = 0; i < matrices.size(); i++) {
200        mMatrices.add(matrices.itemAt(i));
201    }
202
203    mPathHeap = recorder.mPathHeap;
204    if (mPathHeap) {
205        mPathHeap->safeRef();
206    }
207}
208
209void DisplayList::init() {
210    mPathHeap = NULL;
211}
212
213void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
214    TextContainer text;
215    mReader.rewind();
216
217#if DEBUG_DISPLAY_LIST
218    uint32_t count = (level + 1) * 2;
219    char indent[count + 1];
220    for (uint32_t i = 0; i < count; i++) {
221        indent[i] = ' ';
222    }
223    indent[count] = '\0';
224    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
225#endif
226
227    int saveCount = renderer.getSaveCount() - 1;
228    while (!mReader.eof()) {
229        int op = mReader.readInt();
230        DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
231
232        switch (op) {
233            case AcquireContext: {
234                renderer.acquireContext();
235            }
236            break;
237            case ReleaseContext: {
238                renderer.releaseContext();
239            }
240            break;
241            case Save: {
242                renderer.save(getInt());
243            }
244            break;
245            case Restore: {
246                renderer.restore();
247            }
248            break;
249            case RestoreToCount: {
250                renderer.restoreToCount(saveCount + getInt());
251            }
252            break;
253            case SaveLayer: {
254                renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
255                        getPaint(), getInt());
256            }
257            break;
258            case SaveLayerAlpha: {
259                renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
260                        getInt(), getInt());
261            }
262            break;
263            case Translate: {
264                renderer.translate(getFloat(), getFloat());
265            }
266            break;
267            case Rotate: {
268                renderer.rotate(getFloat());
269            }
270            break;
271            case Scale: {
272                renderer.scale(getFloat(), getFloat());
273            }
274            break;
275            case Skew: {
276                renderer.skew(getFloat(), getFloat());
277            }
278            break;
279            case SetMatrix: {
280                renderer.setMatrix(getMatrix());
281            }
282            break;
283            case ConcatMatrix: {
284                renderer.concatMatrix(getMatrix());
285            }
286            break;
287            case ClipRect: {
288                renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
289                        (SkRegion::Op) getInt());
290            }
291            break;
292            case DrawDisplayList: {
293                renderer.drawDisplayList(getDisplayList(), level + 1);
294            }
295            break;
296            case DrawLayer: {
297                renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint());
298            }
299            break;
300            case DrawBitmap: {
301                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
302            }
303            break;
304            case DrawBitmapMatrix: {
305                renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
306            }
307            break;
308            case DrawBitmapRect: {
309                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
310                        getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
311            }
312            break;
313            case DrawBitmapMesh: {
314                int verticesCount = 0;
315                uint32_t colorsCount = 0;
316
317                SkBitmap* bitmap = getBitmap();
318                uint32_t meshWidth = getInt();
319                uint32_t meshHeight = getInt();
320                float* vertices = getFloats(verticesCount);
321                bool hasColors = getInt();
322                int* colors = hasColors ? getInts(colorsCount) : NULL;
323
324                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
325            }
326            case DrawPatch: {
327                int32_t* xDivs = NULL;
328                int32_t* yDivs = NULL;
329                uint32_t* colors = NULL;
330                uint32_t xDivsCount = 0;
331                uint32_t yDivsCount = 0;
332                int8_t numColors = 0;
333
334                SkBitmap* bitmap = getBitmap();
335
336                xDivs = getInts(xDivsCount);
337                yDivs = getInts(yDivsCount);
338                colors = getUInts(numColors);
339
340                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
341                        numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
342            }
343            break;
344            case DrawColor: {
345                renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
346            }
347            break;
348            case DrawRect: {
349                renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
350            }
351            break;
352            case DrawRoundRect: {
353                renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
354                        getFloat(), getFloat(), getPaint());
355            }
356            break;
357            case DrawCircle: {
358                renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
359            }
360            break;
361            case DrawPath: {
362                renderer.drawPath(getPath(), getPaint());
363            }
364            break;
365            case DrawLines: {
366                int count = 0;
367                float* points = getFloats(count);
368                renderer.drawLines(points, count, getPaint());
369            }
370            break;
371            case DrawText: {
372                getText(&text);
373                renderer.drawText(text.text(), text.length(), getInt(),
374                        getFloat(), getFloat(), getPaint());
375            }
376            break;
377            case ResetShader: {
378                renderer.resetShader();
379            }
380            break;
381            case SetupShader: {
382                renderer.setupShader(getShader());
383            }
384            break;
385            case ResetColorFilter: {
386                renderer.resetColorFilter();
387            }
388            break;
389            case SetupColorFilter: {
390                renderer.setupColorFilter(getColorFilter());
391            }
392            break;
393            case ResetShadow: {
394                renderer.resetShadow();
395            }
396            break;
397            case SetupShadow: {
398                renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
399            }
400            break;
401        }
402    }
403
404    DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2);
405}
406
407///////////////////////////////////////////////////////////////////////////////
408// Base structure
409///////////////////////////////////////////////////////////////////////////////
410
411DisplayListRenderer::DisplayListRenderer():
412        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
413    mPathHeap = NULL;
414    mDisplayList = NULL;
415}
416
417DisplayListRenderer::~DisplayListRenderer() {
418    reset();
419}
420
421void DisplayListRenderer::reset() {
422    if (mPathHeap) {
423        mPathHeap->unref();
424        mPathHeap = NULL;
425    }
426
427    mWriter.reset();
428    mHeap.reset();
429
430    mRCRecorder.reset();
431    mTFRecorder.reset();
432
433    Caches& caches = Caches::getInstance();
434    for (size_t i = 0; i < mBitmapResources.size(); i++) {
435        SkBitmap* resource = mBitmapResources.itemAt(i);
436        caches.resourceCache.decrementRefcount(resource);
437    }
438    mBitmapResources.clear();
439
440    for (size_t i = 0; i < mShaders.size(); i++) {
441       caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
442    }
443    mShaders.clear();
444    mShaderMap.clear();
445
446    mPaints.clear();
447    mPaintMap.clear();
448    mMatrices.clear();
449}
450
451///////////////////////////////////////////////////////////////////////////////
452// Operations
453///////////////////////////////////////////////////////////////////////////////
454
455DisplayList* DisplayListRenderer::getDisplayList() {
456    if (mDisplayList == NULL) {
457        mDisplayList = new DisplayList(*this);
458    } else {
459        mDisplayList->initFromDisplayListRenderer(*this);
460    }
461    return mDisplayList;
462}
463
464void DisplayListRenderer::setViewport(int width, int height) {
465    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
466
467    mWidth = width;
468    mHeight = height;
469}
470
471void DisplayListRenderer::prepare(bool opaque) {
472    mSnapshot = new Snapshot(mFirstSnapshot,
473            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
474    mSaveCount = 1;
475    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
476}
477
478void DisplayListRenderer::acquireContext() {
479    addOp(DisplayList::AcquireContext);
480    OpenGLRenderer::acquireContext();
481}
482
483void DisplayListRenderer::releaseContext() {
484    addOp(DisplayList::ReleaseContext);
485    OpenGLRenderer::releaseContext();
486}
487
488int DisplayListRenderer::save(int flags) {
489    addOp(DisplayList::Save);
490    addInt(flags);
491    return OpenGLRenderer::save(flags);
492}
493
494void DisplayListRenderer::restore() {
495    addOp(DisplayList::Restore);
496    OpenGLRenderer::restore();
497}
498
499void DisplayListRenderer::restoreToCount(int saveCount) {
500    addOp(DisplayList::RestoreToCount);
501    addInt(saveCount);
502    OpenGLRenderer::restoreToCount(saveCount);
503}
504
505int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
506        SkPaint* p, int flags) {
507    addOp(DisplayList::SaveLayer);
508    addBounds(left, top, right, bottom);
509    addPaint(p);
510    addInt(flags);
511    return OpenGLRenderer::save(flags);
512}
513
514int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
515        int alpha, int flags) {
516    addOp(DisplayList::SaveLayerAlpha);
517    addBounds(left, top, right, bottom);
518    addInt(alpha);
519    addInt(flags);
520    return OpenGLRenderer::save(flags);
521}
522
523void DisplayListRenderer::translate(float dx, float dy) {
524    addOp(DisplayList::Translate);
525    addPoint(dx, dy);
526    OpenGLRenderer::translate(dx, dy);
527}
528
529void DisplayListRenderer::rotate(float degrees) {
530    addOp(DisplayList::Rotate);
531    addFloat(degrees);
532    OpenGLRenderer::rotate(degrees);
533}
534
535void DisplayListRenderer::scale(float sx, float sy) {
536    addOp(DisplayList::Scale);
537    addPoint(sx, sy);
538    OpenGLRenderer::scale(sx, sy);
539}
540
541void DisplayListRenderer::skew(float sx, float sy) {
542    addOp(DisplayList::Skew);
543    addPoint(sx, sy);
544    OpenGLRenderer::skew(sx, sy);
545}
546
547void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
548    addOp(DisplayList::SetMatrix);
549    addMatrix(matrix);
550    OpenGLRenderer::setMatrix(matrix);
551}
552
553void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
554    addOp(DisplayList::ConcatMatrix);
555    addMatrix(matrix);
556    OpenGLRenderer::concatMatrix(matrix);
557}
558
559bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
560        SkRegion::Op op) {
561    addOp(DisplayList::ClipRect);
562    addBounds(left, top, right, bottom);
563    addInt(op);
564    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
565}
566
567void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
568    addOp(DisplayList::DrawDisplayList);
569    addDisplayList(displayList);
570}
571
572void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
573    addOp(DisplayList::DrawLayer);
574    addInt((int) layer);
575    addPoint(x, y);
576    addPaint(paint);
577}
578
579void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
580        SkPaint* paint) {
581    addOp(DisplayList::DrawBitmap);
582    addBitmap(bitmap);
583    addPoint(left, top);
584    addPaint(paint);
585}
586
587void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
588        SkPaint* paint) {
589    addOp(DisplayList::DrawBitmapMatrix);
590    addBitmap(bitmap);
591    addMatrix(matrix);
592    addPaint(paint);
593}
594
595void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
596        float srcRight, float srcBottom, float dstLeft, float dstTop,
597        float dstRight, float dstBottom, SkPaint* paint) {
598    addOp(DisplayList::DrawBitmapRect);
599    addBitmap(bitmap);
600    addBounds(srcLeft, srcTop, srcRight, srcBottom);
601    addBounds(dstLeft, dstTop, dstRight, dstBottom);
602    addPaint(paint);
603}
604
605void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
606        float* vertices, int* colors, SkPaint* paint) {
607    addOp(DisplayList::DrawBitmapMesh);
608    addBitmap(bitmap);
609    addInt(meshWidth);
610    addInt(meshHeight);
611    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
612    if (colors) {
613        addInt(1);
614        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
615    } else {
616        addInt(0);
617    }
618    addPaint(paint);
619}
620
621void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
622        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
623        float left, float top, float right, float bottom, SkPaint* paint) {
624    addOp(DisplayList::DrawPatch);
625    addBitmap(bitmap);
626    addInts(xDivs, width);
627    addInts(yDivs, height);
628    addUInts(colors, numColors);
629    addBounds(left, top, right, bottom);
630    addPaint(paint);
631}
632
633void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
634    addOp(DisplayList::DrawColor);
635    addInt(color);
636    addInt(mode);
637}
638
639void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
640        SkPaint* paint) {
641    addOp(DisplayList::DrawRect);
642    addBounds(left, top, right, bottom);
643    addPaint(paint);
644}
645
646void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
647            float rx, float ry, SkPaint* paint) {
648    addOp(DisplayList::DrawRoundRect);
649    addBounds(left, top, right, bottom);
650    addPoint(rx, ry);
651    addPaint(paint);
652}
653
654void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
655    addOp(DisplayList::DrawCircle);
656    addPoint(x, y);
657    addFloat(radius);
658    addPaint(paint);
659}
660
661void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
662    addOp(DisplayList::DrawPath);
663    addPath(path);
664    addPaint(paint);
665}
666
667void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
668    addOp(DisplayList::DrawLines);
669    addFloats(points, count);
670    addPaint(paint);
671}
672
673void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
674        float x, float y, SkPaint* paint) {
675    addOp(DisplayList::DrawText);
676    addText(text, bytesCount);
677    addInt(count);
678    addPoint(x, y);
679    addPaint(paint);
680}
681
682void DisplayListRenderer::resetShader() {
683    addOp(DisplayList::ResetShader);
684}
685
686void DisplayListRenderer::setupShader(SkiaShader* shader) {
687    addOp(DisplayList::SetupShader);
688    addShader(shader);
689}
690
691void DisplayListRenderer::resetColorFilter() {
692    addOp(DisplayList::ResetColorFilter);
693}
694
695void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
696    addOp(DisplayList::SetupColorFilter);
697    addColorFilter(filter);
698}
699
700void DisplayListRenderer::resetShadow() {
701    addOp(DisplayList::ResetShadow);
702}
703
704void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
705    addOp(DisplayList::SetupShadow);
706    addFloat(radius);
707    addPoint(dx, dy);
708    addInt(color);
709}
710
711}; // namespace uirenderer
712}; // namespace android
713