blob: ee907021bab74aae9a6f7114f469cf3165c3d358 [file] [log] [blame]
Romain Guy4aa90572010-09-26 18:40:37 -07001/*
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///////////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070025// Display list
26///////////////////////////////////////////////////////////////////////////////
27
28DisplayList::DisplayList(const DisplayListRenderer& recorder) {
29 const SkWriter32& writer = recorder.writeStream();
30 init();
31
32 if (writer.size() == 0) {
33 return;
34 }
35
36 size_t size = writer.size();
37 void* buffer = sk_malloc_throw(size);
38 writer.flatten(buffer);
39 mReader.setMemory(buffer, size);
40
41 mRCPlayback.reset(&recorder.mRCRecorder);
42 mRCPlayback.setupBuffer(mReader);
43
44 mTFPlayback.reset(&recorder.mTFRecorder);
45 mTFPlayback.setupBuffer(mReader);
46
47 const SkTDArray<const SkFlatBitmap*>& bitmaps = recorder.getBitmaps();
48 mBitmapCount = bitmaps.count();
49 if (mBitmapCount > 0) {
50 mBitmaps = new SkBitmap[mBitmapCount];
51 for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
52 flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
53 const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
54 int index = flatBitmap->index() - 1;
55 flatBitmap->unflatten(&mBitmaps[index], &mRCPlayback);
56 }
57 }
58
59 const SkTDArray<const SkFlatMatrix*>& matrices = recorder.getMatrices();
60 mMatrixCount = matrices.count();
61 if (mMatrixCount > 0) {
62 mMatrices = new SkMatrix[mMatrixCount];
63 for (const SkFlatMatrix** matrixPtr = matrices.begin();
64 matrixPtr != matrices.end(); matrixPtr++) {
65 const SkFlatMatrix* flatMatrix = *matrixPtr;
66 flatMatrix->unflatten(&mMatrices[flatMatrix->index() - 1]);
67 }
68 }
69
70 const SkTDArray<const SkFlatPaint*>& paints = recorder.getPaints();
71 mPaintCount = paints.count();
72 if (mPaintCount > 0) {
73 mPaints = new SkPaint[mPaintCount];
74 for (const SkFlatPaint** flatPaintPtr = paints.begin();
75 flatPaintPtr != paints.end(); flatPaintPtr++) {
76 const SkFlatPaint* flatPaint = *flatPaintPtr;
77 int index = flatPaint->index() - 1;
78 flatPaint->unflatten(&mPaints[index], &mRCPlayback, &mTFPlayback);
79 }
80 }
81
82 mPathHeap = recorder.mPathHeap;
83 mPathHeap->safeRef();
84}
85
86DisplayList::~DisplayList() {
87 sk_free((void*) mReader.base());
88
89 Caches& caches = Caches::getInstance();
90 for (int i = 0; i < mBitmapCount; i++) {
91 caches.textureCache.remove(&mBitmaps[i]);
92 }
93
94 delete[] mBitmaps;
95 delete[] mMatrices;
96 delete[] mPaints;
97
98 mPathHeap->safeUnref();
99}
100
101void DisplayList::init() {
102 mBitmaps = NULL;
103 mMatrices = NULL;
104 mPaints = NULL;
105 mPathHeap = NULL;
106 mBitmapCount = mMatrixCount = mPaintCount = 0;
107}
108
109void DisplayList::replay(OpenGLRenderer& renderer) {
110 TextContainer text;
111 mReader.rewind();
112
113 int saveCount = renderer.getSaveCount() - 1;
114
115 while (!mReader.eof()) {
116 switch (mReader.readInt()) {
117 case AcquireContext: {
118 renderer.acquireContext();
119 }
120 break;
121 case ReleaseContext: {
122 renderer.releaseContext();
123 }
124 break;
125 case Save: {
126 renderer.save(getInt());
127 }
128 break;
129 case Restore: {
130 renderer.restore();
131 }
132 break;
133 case RestoreToCount: {
134 renderer.restoreToCount(saveCount + getInt());
135 }
136 break;
137 case SaveLayer: {
138 renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
139 getPaint(), getInt());
140 }
141 break;
142 case Translate: {
143 renderer.translate(getFloat(), getFloat());
144 }
145 break;
146 case Rotate: {
147 renderer.rotate(getFloat());
148 }
149 break;
150 case Scale: {
151 renderer.scale(getFloat(), getFloat());
152 }
153 break;
154 case SetMatrix: {
155 renderer.setMatrix(getMatrix());
156 }
157 break;
158 case ConcatMatrix: {
159 renderer.concatMatrix(getMatrix());
160 }
161 break;
162 case ClipRect: {
163 renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
164 (SkRegion::Op) getInt());
165 }
166 break;
167 case DrawBitmap: {
168 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
169 }
170 break;
171 case DrawBitmapMatrix: {
172 renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
173 }
174 break;
175 case DrawBitmapRect: {
176 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
177 getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
178 }
179 break;
180 case DrawPatch: {
181 int32_t* xDivs = NULL;
182 int32_t* yDivs = NULL;
183 uint32_t xDivsCount = 0;
184 uint32_t yDivsCount = 0;
185
186 SkBitmap* bitmap = getBitmap();
187
188 xDivs = getInts(xDivsCount);
189 yDivs = getInts(yDivsCount);
190
191 renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount,
192 getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
193 }
194 break;
195 case DrawColor: {
196 renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
197 }
198 break;
199 case DrawRect: {
200 renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
201 }
202 break;
203 case DrawPath: {
204 renderer.drawPath(getPath(), getPaint());
205 }
206 break;
207 case DrawLines: {
208 int count = 0;
209 float* points = getFloats(count);
210 renderer.drawLines(points, count, getPaint());
211 }
212 break;
213 case DrawText: {
214 getText(&text);
215 renderer.drawText(text.text(), text.length(), getInt(),
216 getFloat(), getFloat(), getPaint());
217 }
218 break;
219 case ResetShader: {
220 renderer.resetShader();
221 }
222 break;
223 case SetupShader: {
224 // TODO: Implement
225 }
226 break;
227 case ResetColorFilter: {
228 renderer.resetColorFilter();
229 }
230 break;
231 case SetupColorFilter: {
232 // TODO: Implement
233 }
234 break;
235 case ResetShadow: {
236 renderer.resetShadow();
237 }
238 break;
239 case SetupShadow: {
240 renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
241 }
242 break;
243 }
244 }
245}
246
247///////////////////////////////////////////////////////////////////////////////
Romain Guy4aa90572010-09-26 18:40:37 -0700248// Base structure
249///////////////////////////////////////////////////////////////////////////////
250
251DisplayListRenderer::DisplayListRenderer():
252 mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
253 mBitmapIndex = mMatrixIndex = mPaintIndex = 1;
254 mPathHeap = NULL;
255}
256
257DisplayListRenderer::~DisplayListRenderer() {
258 reset();
259}
260
261void DisplayListRenderer::reset() {
262 if (mPathHeap) {
263 mPathHeap->unref();
264 mPathHeap = NULL;
265 }
266
267 mBitmaps.reset();
268 mMatrices.reset();
269 mPaints.reset();
270
271 mWriter.reset();
272 mHeap.reset();
273
274 mRCRecorder.reset();
275 mTFRecorder.reset();
276}
277
278///////////////////////////////////////////////////////////////////////////////
279// Operations
280///////////////////////////////////////////////////////////////////////////////
281
Romain Guyb051e892010-09-28 19:09:36 -0700282void DisplayListRenderer::setViewport(int width, int height) {
283 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
284
285 mWidth = width;
286 mHeight = height;
287}
288
289void DisplayListRenderer::prepare() {
290 mSnapshot = new Snapshot(mFirstSnapshot,
291 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
292 mSaveCount = 1;
293 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
294}
295
Romain Guy4aa90572010-09-26 18:40:37 -0700296void DisplayListRenderer::acquireContext() {
Romain Guyb051e892010-09-28 19:09:36 -0700297 addOp(DisplayList::AcquireContext);
Romain Guy4aa90572010-09-26 18:40:37 -0700298 OpenGLRenderer::acquireContext();
299}
300
301void DisplayListRenderer::releaseContext() {
Romain Guyb051e892010-09-28 19:09:36 -0700302 addOp(DisplayList::ReleaseContext);
Romain Guy4aa90572010-09-26 18:40:37 -0700303 OpenGLRenderer::releaseContext();
304}
305
306int DisplayListRenderer::save(int flags) {
Romain Guyb051e892010-09-28 19:09:36 -0700307 addOp(DisplayList::Save);
Romain Guy4aa90572010-09-26 18:40:37 -0700308 addInt(flags);
309 return OpenGLRenderer::save(flags);
310}
311
312void DisplayListRenderer::restore() {
Romain Guyb051e892010-09-28 19:09:36 -0700313 addOp(DisplayList::Restore);
Romain Guy4aa90572010-09-26 18:40:37 -0700314 OpenGLRenderer::restore();
315}
316
317void DisplayListRenderer::restoreToCount(int saveCount) {
Romain Guyb051e892010-09-28 19:09:36 -0700318 addOp(DisplayList::RestoreToCount);
Romain Guy4aa90572010-09-26 18:40:37 -0700319 addInt(saveCount);
320 OpenGLRenderer::restoreToCount(saveCount);
321}
322
323int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
324 const SkPaint* p, int flags) {
Romain Guyb051e892010-09-28 19:09:36 -0700325 addOp(DisplayList::SaveLayer);
Romain Guy4aa90572010-09-26 18:40:37 -0700326 addBounds(left, top, right, bottom);
327 addPaint(p);
328 addInt(flags);
Romain Guyb051e892010-09-28 19:09:36 -0700329 return OpenGLRenderer::save(flags);
Romain Guy4aa90572010-09-26 18:40:37 -0700330}
331
332void DisplayListRenderer::translate(float dx, float dy) {
Romain Guyb051e892010-09-28 19:09:36 -0700333 addOp(DisplayList::Translate);
Romain Guy4aa90572010-09-26 18:40:37 -0700334 addPoint(dx, dy);
335 OpenGLRenderer::translate(dx, dy);
336}
337
338void DisplayListRenderer::rotate(float degrees) {
Romain Guyb051e892010-09-28 19:09:36 -0700339 addOp(DisplayList::Rotate);
Romain Guy4aa90572010-09-26 18:40:37 -0700340 addFloat(degrees);
341 OpenGLRenderer::rotate(degrees);
342}
343
344void DisplayListRenderer::scale(float sx, float sy) {
Romain Guyb051e892010-09-28 19:09:36 -0700345 addOp(DisplayList::Scale);
Romain Guy4aa90572010-09-26 18:40:37 -0700346 addPoint(sx, sy);
347 OpenGLRenderer::scale(sx, sy);
348}
349
350void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
Romain Guyb051e892010-09-28 19:09:36 -0700351 addOp(DisplayList::SetMatrix);
Romain Guy4aa90572010-09-26 18:40:37 -0700352 addMatrix(matrix);
353 OpenGLRenderer::setMatrix(matrix);
354}
355
356void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
Romain Guyb051e892010-09-28 19:09:36 -0700357 addOp(DisplayList::ConcatMatrix);
Romain Guy4aa90572010-09-26 18:40:37 -0700358 addMatrix(matrix);
359 OpenGLRenderer::concatMatrix(matrix);
360}
361
362bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
363 SkRegion::Op op) {
Romain Guyb051e892010-09-28 19:09:36 -0700364 addOp(DisplayList::ClipRect);
Romain Guy4aa90572010-09-26 18:40:37 -0700365 addBounds(left, top, right, bottom);
366 addInt(op);
367 return OpenGLRenderer::clipRect(left, top, right, bottom, op);
368}
369
370void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
371 const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700372 addOp(DisplayList::DrawBitmap);
Romain Guy4aa90572010-09-26 18:40:37 -0700373 addBitmap(bitmap);
374 addPoint(left, top);
375 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700376}
377
378void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
379 const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700380 addOp(DisplayList::DrawBitmapMatrix);
Romain Guy4aa90572010-09-26 18:40:37 -0700381 addBitmap(bitmap);
382 addMatrix(matrix);
383 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700384}
385
386void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
387 float srcRight, float srcBottom, float dstLeft, float dstTop,
388 float dstRight, float dstBottom, const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700389 addOp(DisplayList::DrawBitmapRect);
Romain Guy4aa90572010-09-26 18:40:37 -0700390 addBitmap(bitmap);
391 addBounds(srcLeft, srcTop, srcRight, srcBottom);
392 addBounds(dstLeft, dstTop, dstRight, dstBottom);
393 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700394}
395
396void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
397 uint32_t width, uint32_t height, float left, float top, float right, float bottom,
398 const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700399 addOp(DisplayList::DrawPatch);
Romain Guy4aa90572010-09-26 18:40:37 -0700400 addBitmap(bitmap);
401 addInts(xDivs, width);
402 addInts(yDivs, height);
403 addBounds(left, top, right, bottom);
404 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700405}
406
407void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
Romain Guyb051e892010-09-28 19:09:36 -0700408 addOp(DisplayList::DrawColor);
Romain Guy4aa90572010-09-26 18:40:37 -0700409 addInt(color);
410 addInt(mode);
Romain Guy4aa90572010-09-26 18:40:37 -0700411}
412
413void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
414 const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700415 addOp(DisplayList::DrawRect);
Romain Guy4aa90572010-09-26 18:40:37 -0700416 addBounds(left, top, right, bottom);
417 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700418}
419
420void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700421 addOp(DisplayList::DrawPath);
Romain Guy4aa90572010-09-26 18:40:37 -0700422 addPath(path);
423 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700424}
425
426void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700427 addOp(DisplayList::DrawLines);
Romain Guy4aa90572010-09-26 18:40:37 -0700428 addFloats(points, count);
429 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700430}
431
432void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
433 float x, float y, SkPaint* paint) {
Romain Guyb051e892010-09-28 19:09:36 -0700434 addOp(DisplayList::DrawText);
Romain Guy4aa90572010-09-26 18:40:37 -0700435 addText(text, bytesCount);
436 addInt(count);
437 addPoint(x, y);
438 addPaint(paint);
Romain Guy4aa90572010-09-26 18:40:37 -0700439}
440
441void DisplayListRenderer::resetShader() {
Romain Guyb051e892010-09-28 19:09:36 -0700442 addOp(DisplayList::ResetShader);
Romain Guy4aa90572010-09-26 18:40:37 -0700443 OpenGLRenderer::resetShader();
444}
445
446void DisplayListRenderer::setupShader(SkiaShader* shader) {
447 // TODO: Implement
448 OpenGLRenderer::setupShader(shader);
449}
450
451void DisplayListRenderer::resetColorFilter() {
Romain Guyb051e892010-09-28 19:09:36 -0700452 addOp(DisplayList::ResetColorFilter);
Romain Guy4aa90572010-09-26 18:40:37 -0700453 OpenGLRenderer::resetColorFilter();
454}
455
456void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
457 // TODO: Implement
458 OpenGLRenderer::setupColorFilter(filter);
459}
460
461void DisplayListRenderer::resetShadow() {
Romain Guyb051e892010-09-28 19:09:36 -0700462 addOp(DisplayList::ResetShadow);
Romain Guy4aa90572010-09-26 18:40:37 -0700463 OpenGLRenderer::resetShadow();
464}
465
466void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
Romain Guyb051e892010-09-28 19:09:36 -0700467 addOp(DisplayList::SetupShadow);
Romain Guy4aa90572010-09-26 18:40:37 -0700468 addFloat(radius);
469 addPoint(dx, dy);
470 addInt(color);
471 OpenGLRenderer::setupShadow(radius, dx, dy, color);
472}
473
474///////////////////////////////////////////////////////////////////////////////
475// Recording management
476///////////////////////////////////////////////////////////////////////////////
477
478int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) {
479 if (paint == NULL) {
480 return 0;
481 }
482
483 SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex,
484 &mRCRecorder, &mTFRecorder);
485 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
486 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
487 if (index >= 0) {
488 (void) mHeap.unalloc(flat);
489 return paints[index]->index();
490 }
491
492 index = ~index;
493 *paints.insert(index) = flat;
494 return mPaintIndex++;
495}
496
497int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) {
498 if (matrix == NULL) {
499 return 0;
500 }
501
502 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex);
503 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
504 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
505 if (index >= 0) {
506 (void) mHeap.unalloc(flat);
507 return matrices[index]->index();
508 }
509 index = ~index;
510 *matrices.insert(index) = flat;
511 return mMatrixIndex++;
512}
513
514int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) {
515 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder);
516 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
517 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
518 if (index >= 0) {
519 (void) mHeap.unalloc(flat);
520 return bitmaps[index]->index();
521 }
522 index = ~index;
523 *bitmaps.insert(index) = flat;
524 return mBitmapIndex++;
525}
526
527}; // namespace uirenderer
528}; // namespace android