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