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