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