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