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