DisplayListRenderer.cpp revision 27454a42de8b3c54cdd3b2b2a12446c2c10c8cb9
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    mRestoreSaveCount = -1;
477}
478
479void DisplayListRenderer::finish() {
480    insertRestoreToCount();
481    OpenGLRenderer::finish();
482}
483
484void DisplayListRenderer::acquireContext() {
485    addOp(DisplayList::AcquireContext);
486    OpenGLRenderer::acquireContext();
487}
488
489void DisplayListRenderer::releaseContext() {
490    addOp(DisplayList::ReleaseContext);
491    OpenGLRenderer::releaseContext();
492}
493
494int DisplayListRenderer::save(int flags) {
495    addOp(DisplayList::Save);
496    addInt(flags);
497    return OpenGLRenderer::save(flags);
498}
499
500void DisplayListRenderer::restore() {
501    addOp(DisplayList::Restore);
502    OpenGLRenderer::restore();
503}
504
505void DisplayListRenderer::restoreToCount(int saveCount) {
506    mRestoreSaveCount = saveCount;
507    OpenGLRenderer::restoreToCount(saveCount);
508}
509
510int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
511        SkPaint* p, int flags) {
512    addOp(DisplayList::SaveLayer);
513    addBounds(left, top, right, bottom);
514    addPaint(p);
515    addInt(flags);
516    return OpenGLRenderer::save(flags);
517}
518
519int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
520        int alpha, int flags) {
521    addOp(DisplayList::SaveLayerAlpha);
522    addBounds(left, top, right, bottom);
523    addInt(alpha);
524    addInt(flags);
525    return OpenGLRenderer::save(flags);
526}
527
528void DisplayListRenderer::translate(float dx, float dy) {
529    addOp(DisplayList::Translate);
530    addPoint(dx, dy);
531    OpenGLRenderer::translate(dx, dy);
532}
533
534void DisplayListRenderer::rotate(float degrees) {
535    addOp(DisplayList::Rotate);
536    addFloat(degrees);
537    OpenGLRenderer::rotate(degrees);
538}
539
540void DisplayListRenderer::scale(float sx, float sy) {
541    addOp(DisplayList::Scale);
542    addPoint(sx, sy);
543    OpenGLRenderer::scale(sx, sy);
544}
545
546void DisplayListRenderer::skew(float sx, float sy) {
547    addOp(DisplayList::Skew);
548    addPoint(sx, sy);
549    OpenGLRenderer::skew(sx, sy);
550}
551
552void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
553    addOp(DisplayList::SetMatrix);
554    addMatrix(matrix);
555    OpenGLRenderer::setMatrix(matrix);
556}
557
558void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
559    addOp(DisplayList::ConcatMatrix);
560    addMatrix(matrix);
561    OpenGLRenderer::concatMatrix(matrix);
562}
563
564bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
565        SkRegion::Op op) {
566    addOp(DisplayList::ClipRect);
567    addBounds(left, top, right, bottom);
568    addInt(op);
569    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
570}
571
572void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
573    addOp(DisplayList::DrawDisplayList);
574    addDisplayList(displayList);
575}
576
577void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
578    addOp(DisplayList::DrawLayer);
579    addInt((int) layer);
580    addPoint(x, y);
581    addPaint(paint);
582}
583
584void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
585        SkPaint* paint) {
586    addOp(DisplayList::DrawBitmap);
587    addBitmap(bitmap);
588    addPoint(left, top);
589    addPaint(paint);
590}
591
592void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
593        SkPaint* paint) {
594    addOp(DisplayList::DrawBitmapMatrix);
595    addBitmap(bitmap);
596    addMatrix(matrix);
597    addPaint(paint);
598}
599
600void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
601        float srcRight, float srcBottom, float dstLeft, float dstTop,
602        float dstRight, float dstBottom, SkPaint* paint) {
603    addOp(DisplayList::DrawBitmapRect);
604    addBitmap(bitmap);
605    addBounds(srcLeft, srcTop, srcRight, srcBottom);
606    addBounds(dstLeft, dstTop, dstRight, dstBottom);
607    addPaint(paint);
608}
609
610void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
611        float* vertices, int* colors, SkPaint* paint) {
612    addOp(DisplayList::DrawBitmapMesh);
613    addBitmap(bitmap);
614    addInt(meshWidth);
615    addInt(meshHeight);
616    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
617    if (colors) {
618        addInt(1);
619        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
620    } else {
621        addInt(0);
622    }
623    addPaint(paint);
624}
625
626void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
627        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
628        float left, float top, float right, float bottom, SkPaint* paint) {
629    addOp(DisplayList::DrawPatch);
630    addBitmap(bitmap);
631    addInts(xDivs, width);
632    addInts(yDivs, height);
633    addUInts(colors, numColors);
634    addBounds(left, top, right, bottom);
635    addPaint(paint);
636}
637
638void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
639    addOp(DisplayList::DrawColor);
640    addInt(color);
641    addInt(mode);
642}
643
644void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
645        SkPaint* paint) {
646    addOp(DisplayList::DrawRect);
647    addBounds(left, top, right, bottom);
648    addPaint(paint);
649}
650
651void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
652            float rx, float ry, SkPaint* paint) {
653    addOp(DisplayList::DrawRoundRect);
654    addBounds(left, top, right, bottom);
655    addPoint(rx, ry);
656    addPaint(paint);
657}
658
659void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
660    addOp(DisplayList::DrawCircle);
661    addPoint(x, y);
662    addFloat(radius);
663    addPaint(paint);
664}
665
666void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
667    addOp(DisplayList::DrawPath);
668    addPath(path);
669    addPaint(paint);
670}
671
672void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
673    addOp(DisplayList::DrawLines);
674    addFloats(points, count);
675    addPaint(paint);
676}
677
678void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
679        float x, float y, SkPaint* paint) {
680    addOp(DisplayList::DrawText);
681    addText(text, bytesCount);
682    addInt(count);
683    addPoint(x, y);
684    addPaint(paint);
685}
686
687void DisplayListRenderer::resetShader() {
688    addOp(DisplayList::ResetShader);
689}
690
691void DisplayListRenderer::setupShader(SkiaShader* shader) {
692    addOp(DisplayList::SetupShader);
693    addShader(shader);
694}
695
696void DisplayListRenderer::resetColorFilter() {
697    addOp(DisplayList::ResetColorFilter);
698}
699
700void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
701    addOp(DisplayList::SetupColorFilter);
702    addColorFilter(filter);
703}
704
705void DisplayListRenderer::resetShadow() {
706    addOp(DisplayList::ResetShadow);
707}
708
709void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
710    addOp(DisplayList::SetupShadow);
711    addFloat(radius);
712    addPoint(dx, dy);
713    addInt(color);
714}
715
716}; // namespace uirenderer
717}; // namespace android
718