blob: 17ed8ac5fe209458d10fc45366e5f7c4af43a39e [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
Romain Guyd5a85fb2012-03-13 11:18:20 -070019#include <SkCamera.h>
Chet Haase9c1e23b2011-03-24 10:51:31 -070020
Romain Guy65549432012-03-26 16:45:05 -070021#include <private/hwui/DrawGlInfo.h>
22
Chet Haase9c1e23b2011-03-24 10:51:31 -070023#include "DisplayListLogBuffer.h"
Chris Craik2af46352012-11-26 18:30:17 -080024#include "DisplayListOp.h"
Romain Guy4aa90572010-09-26 18:40:37 -070025#include "DisplayListRenderer.h"
Chet Haase9c1e23b2011-03-24 10:51:31 -070026#include "Caches.h"
Romain Guy13631f32012-01-30 17:41:55 -080027
Romain Guy4aa90572010-09-26 18:40:37 -070028namespace android {
29namespace uirenderer {
30
31///////////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070032// Display list
33///////////////////////////////////////////////////////////////////////////////
34
Chet Haase9c1e23b2011-03-24 10:51:31 -070035void DisplayList::outputLogBuffer(int fd) {
36 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
37 if (logBuffer.isEmpty()) {
38 return;
39 }
Romain Guy65b345f2011-07-27 18:51:50 -070040
Chet Haase9c1e23b2011-03-24 10:51:31 -070041 FILE *file = fdopen(fd, "a");
Romain Guy65b345f2011-07-27 18:51:50 -070042
Chet Haase9c1e23b2011-03-24 10:51:31 -070043 fprintf(file, "\nRecent DisplayList operations\n");
Chris Craik2af46352012-11-26 18:30:17 -080044 logBuffer.outputCommands(file);
Romain Guy65b345f2011-07-27 18:51:50 -070045
46 String8 cachesLog;
47 Caches::getInstance().dumpMemoryUsage(cachesLog);
48 fprintf(file, "\nCaches:\n%s", cachesLog.string());
49 fprintf(file, "\n");
50
Chet Haase9c1e23b2011-03-24 10:51:31 -070051 fflush(file);
52}
53
Chet Haase491189f2012-03-13 11:42:34 -070054DisplayList::DisplayList(const DisplayListRenderer& recorder) :
Chet Haase9420abd2012-03-29 16:28:32 -070055 mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
56 mStaticMatrix(NULL), mAnimationMatrix(NULL) {
Chet Haase491189f2012-03-13 11:42:34 -070057
Chet Haase5977baa2011-01-05 18:01:22 -080058 initFromDisplayListRenderer(recorder);
59}
60
61DisplayList::~DisplayList() {
Chet Haased63cbd12011-02-03 16:32:46 -080062 clearResources();
63}
64
Romain Guybb0acdf2012-03-05 13:44:35 -080065void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
66 if (displayList) {
67 DISPLAY_LIST_LOGD("Deferring display list destruction");
68 Caches::getInstance().deleteDisplayListDeferred(displayList);
69 }
70}
71
Chet Haased63cbd12011-02-03 16:32:46 -080072void DisplayList::clearResources() {
Chris Craik2af46352012-11-26 18:30:17 -080073 mDisplayListData = NULL;
Chet Haase1271e2c2012-04-20 09:54:27 -070074 delete mTransformMatrix;
75 delete mTransformCamera;
76 delete mTransformMatrix3D;
77 delete mStaticMatrix;
78 delete mAnimationMatrix;
Romain Guy58ecc202012-09-07 11:58:36 -070079
Chet Haase1271e2c2012-04-20 09:54:27 -070080 mTransformMatrix = NULL;
81 mTransformCamera = NULL;
82 mTransformMatrix3D = NULL;
83 mStaticMatrix = NULL;
84 mAnimationMatrix = NULL;
Chet Haasea1cff502012-02-21 13:43:44 -080085
Chet Haase5977baa2011-01-05 18:01:22 -080086 Caches& caches = Caches::getInstance();
Romain Guy54c1a642012-09-27 17:55:46 -070087 caches.unregisterFunctors(mFunctorCount);
Romain Guy58ecc202012-09-07 11:58:36 -070088 caches.resourceCache.lock();
Chet Haase5977baa2011-01-05 18:01:22 -080089
90 for (size_t i = 0; i < mBitmapResources.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -070091 caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
Chet Haase5977baa2011-01-05 18:01:22 -080092 }
Chet Haase5977baa2011-01-05 18:01:22 -080093
Romain Guy49c5fc02012-05-15 11:10:01 -070094 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
95 SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
Romain Guy58ecc202012-09-07 11:58:36 -070096 caches.resourceCache.decrementRefcountLocked(bitmap);
97 caches.resourceCache.destructorLocked(bitmap);
Romain Guy49c5fc02012-05-15 11:10:01 -070098 }
Romain Guy49c5fc02012-05-15 11:10:01 -070099
Romain Guyd586ad92011-06-22 16:14:36 -0700100 for (size_t i = 0; i < mFilterResources.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700101 caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
Romain Guyd586ad92011-06-22 16:14:36 -0700102 }
Romain Guyd586ad92011-06-22 16:14:36 -0700103
Romain Guy24c00212011-01-14 15:31:00 -0800104 for (size_t i = 0; i < mShaders.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700105 caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
106 caches.resourceCache.destructorLocked(mShaders.itemAt(i));
Chet Haase5977baa2011-01-05 18:01:22 -0800107 }
Romain Guy58ecc202012-09-07 11:58:36 -0700108
109 for (size_t i = 0; i < mSourcePaths.size(); i++) {
110 caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
111 }
112
Chet Haase603f6de2012-09-14 15:31:25 -0700113 for (size_t i = 0; i < mLayers.size(); i++) {
114 caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
115 }
116
Romain Guy58ecc202012-09-07 11:58:36 -0700117 caches.resourceCache.unlock();
Chet Haase5977baa2011-01-05 18:01:22 -0800118
119 for (size_t i = 0; i < mPaints.size(); i++) {
120 delete mPaints.itemAt(i);
121 }
Chet Haase5977baa2011-01-05 18:01:22 -0800122
Romain Guy735738c2012-12-03 12:34:51 -0800123 for (size_t i = 0; i < mRegions.size(); i++) {
124 delete mRegions.itemAt(i);
125 }
126
Romain Guy2fc941e2011-02-03 15:06:05 -0800127 for (size_t i = 0; i < mPaths.size(); i++) {
Romain Guy1af23a32011-03-24 16:03:55 -0700128 SkPath* path = mPaths.itemAt(i);
129 caches.pathCache.remove(path);
130 delete path;
Romain Guy2fc941e2011-02-03 15:06:05 -0800131 }
Chet Haased34dd712012-05-02 18:50:34 -0700132
Chet Haase5977baa2011-01-05 18:01:22 -0800133 for (size_t i = 0; i < mMatrices.size(); i++) {
134 delete mMatrices.itemAt(i);
135 }
Romain Guy58ecc202012-09-07 11:58:36 -0700136
137 mBitmapResources.clear();
138 mOwnedBitmapResources.clear();
139 mFilterResources.clear();
140 mShaders.clear();
141 mSourcePaths.clear();
142 mPaints.clear();
Romain Guy735738c2012-12-03 12:34:51 -0800143 mRegions.clear();
Romain Guy58ecc202012-09-07 11:58:36 -0700144 mPaths.clear();
Chet Haase5977baa2011-01-05 18:01:22 -0800145 mMatrices.clear();
Chet Haase603f6de2012-09-14 15:31:25 -0700146 mLayers.clear();
Chet Haase5977baa2011-01-05 18:01:22 -0800147}
148
Chet Haase6a2d17f2012-09-30 12:14:13 -0700149void DisplayList::reset() {
150 clearResources();
151 init();
152}
153
Chet Haased63cbd12011-02-03 16:32:46 -0800154void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
Chet Haased63cbd12011-02-03 16:32:46 -0800155 if (reusing) {
156 // re-using display list - clear out previous allocations
157 clearResources();
158 }
Romain Guy034de6b2012-09-27 19:01:55 -0700159
160 init();
Chet Haased63cbd12011-02-03 16:32:46 -0800161
Chris Craik2af46352012-11-26 18:30:17 -0800162 mDisplayListData = recorder.getDisplayListData();
163 mSize = mDisplayListData->allocator.usedSize();
164
165 if (mSize == 0) {
Romain Guy034de6b2012-09-27 19:01:55 -0700166 return;
167 }
168
Romain Guy54c1a642012-09-27 17:55:46 -0700169 mFunctorCount = recorder.getFunctorCount();
170
Chet Haase5c13d892010-10-08 08:37:55 -0700171 Caches& caches = Caches::getInstance();
Romain Guy54c1a642012-09-27 17:55:46 -0700172 caches.registerFunctors(mFunctorCount);
Romain Guy58ecc202012-09-07 11:58:36 -0700173 caches.resourceCache.lock();
Romain Guyb051e892010-09-28 19:09:36 -0700174
Romain Guy49c5fc02012-05-15 11:10:01 -0700175 const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
Chet Haase5c13d892010-10-08 08:37:55 -0700176 for (size_t i = 0; i < bitmapResources.size(); i++) {
177 SkBitmap* resource = bitmapResources.itemAt(i);
178 mBitmapResources.add(resource);
Romain Guy58ecc202012-09-07 11:58:36 -0700179 caches.resourceCache.incrementRefcountLocked(resource);
Romain Guyb051e892010-09-28 19:09:36 -0700180 }
Chet Haased98aa2d2010-10-25 15:47:32 -0700181
Romain Guy49c5fc02012-05-15 11:10:01 -0700182 const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
183 for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
184 SkBitmap* resource = ownedBitmapResources.itemAt(i);
185 mOwnedBitmapResources.add(resource);
Romain Guy58ecc202012-09-07 11:58:36 -0700186 caches.resourceCache.incrementRefcountLocked(resource);
Romain Guy49c5fc02012-05-15 11:10:01 -0700187 }
188
189 const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
Romain Guyd586ad92011-06-22 16:14:36 -0700190 for (size_t i = 0; i < filterResources.size(); i++) {
191 SkiaColorFilter* resource = filterResources.itemAt(i);
192 mFilterResources.add(resource);
Romain Guy58ecc202012-09-07 11:58:36 -0700193 caches.resourceCache.incrementRefcountLocked(resource);
Romain Guyd586ad92011-06-22 16:14:36 -0700194 }
195
Romain Guy49c5fc02012-05-15 11:10:01 -0700196 const Vector<SkiaShader*>& shaders = recorder.getShaders();
Romain Guy24c00212011-01-14 15:31:00 -0800197 for (size_t i = 0; i < shaders.size(); i++) {
Romain Guyd586ad92011-06-22 16:14:36 -0700198 SkiaShader* resource = shaders.itemAt(i);
199 mShaders.add(resource);
Romain Guy58ecc202012-09-07 11:58:36 -0700200 caches.resourceCache.incrementRefcountLocked(resource);
Romain Guyb051e892010-09-28 19:09:36 -0700201 }
202
Romain Guy58ecc202012-09-07 11:58:36 -0700203 const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
204 for (size_t i = 0; i < sourcePaths.size(); i++) {
205 mSourcePaths.add(sourcePaths.itemAt(i));
206 caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
207 }
208
Chet Haase603f6de2012-09-14 15:31:25 -0700209 const Vector<Layer*>& layers = recorder.getLayers();
210 for (size_t i = 0; i < layers.size(); i++) {
211 mLayers.add(layers.itemAt(i));
212 caches.resourceCache.incrementRefcountLocked(layers.itemAt(i));
213 }
214
Romain Guy58ecc202012-09-07 11:58:36 -0700215 caches.resourceCache.unlock();
216
Romain Guy735738c2012-12-03 12:34:51 -0800217 mPaints.appendVector(recorder.getPaints());
218 mRegions.appendVector(recorder.getRegions());
219 mPaths.appendVector(recorder.getPaths());
220 mMatrices.appendVector(recorder.getMatrices());
Romain Guyb051e892010-09-28 19:09:36 -0700221}
222
Romain Guyb051e892010-09-28 19:09:36 -0700223void DisplayList::init() {
Romain Guy65b345f2011-07-27 18:51:50 -0700224 mSize = 0;
Romain Guy04c9d8c2011-08-25 14:01:48 -0700225 mIsRenderable = true;
Romain Guy034de6b2012-09-27 19:01:55 -0700226 mFunctorCount = 0;
Chet Haase6a2d17f2012-09-30 12:14:13 -0700227 mLeft = 0;
228 mTop = 0;
229 mRight = 0;
230 mBottom = 0;
231 mClipChildren = true;
232 mAlpha = 1;
233 mMultipliedAlpha = 255;
234 mHasOverlappingRendering = true;
235 mTranslationX = 0;
236 mTranslationY = 0;
237 mRotation = 0;
238 mRotationX = 0;
239 mRotationY= 0;
240 mScaleX = 1;
241 mScaleY = 1;
242 mPivotX = 0;
243 mPivotY = 0;
244 mCameraDistance = 0;
245 mMatrixDirty = false;
246 mMatrixFlags = 0;
247 mPrevWidth = -1;
248 mPrevHeight = -1;
249 mWidth = 0;
250 mHeight = 0;
251 mPivotExplicitlySet = false;
252 mCaching = false;
Romain Guy65b345f2011-07-27 18:51:50 -0700253}
254
255size_t DisplayList::getSize() {
256 return mSize;
Romain Guyb051e892010-09-28 19:09:36 -0700257}
258
Chet Haaseed30fd82011-04-22 16:18:45 -0700259/**
260 * This function is a simplified version of replay(), where we simply retrieve and log the
261 * display list. This function should remain in sync with the replay() function.
262 */
Chris Craik2af46352012-11-26 18:30:17 -0800263void DisplayList::output(uint32_t level) {
264 ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this,
Romain Guyddf74372012-05-22 14:07:07 -0700265 mName.string(), isRenderable());
Chet Haaseed30fd82011-04-22 16:18:45 -0700266
Chris Craik3dc553b2013-02-04 12:45:13 -0800267 ALOGD("%*s%s %d", level * 2, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
Chris Craik2af46352012-11-26 18:30:17 -0800268 outputViewProperties(level);
269 int flags = DisplayListOp::kOpLogFlag_Recurse;
270 for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
271 mDisplayListData->displayListOps[i]->output(level, flags);
Chet Haaseed30fd82011-04-22 16:18:45 -0700272 }
Chris Craik2af46352012-11-26 18:30:17 -0800273 ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string());
Chet Haaseed30fd82011-04-22 16:18:45 -0700274}
275
Chet Haasea1cff502012-02-21 13:43:44 -0800276void DisplayList::updateMatrix() {
277 if (mMatrixDirty) {
278 if (!mTransformMatrix) {
279 mTransformMatrix = new SkMatrix();
280 }
281 if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
282 mTransformMatrix->reset();
283 } else {
284 if (!mPivotExplicitlySet) {
285 if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
286 mPrevWidth = mWidth;
287 mPrevHeight = mHeight;
288 mPivotX = mPrevWidth / 2;
289 mPivotY = mPrevHeight / 2;
290 }
291 }
292 if ((mMatrixFlags & ROTATION_3D) == 0) {
293 mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
294 mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
295 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
296 } else {
297 if (!mTransformCamera) {
298 mTransformCamera = new Sk3DView();
299 mTransformMatrix3D = new SkMatrix();
300 }
301 mTransformMatrix->reset();
302 mTransformCamera->save();
303 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
304 mTransformCamera->rotateX(mRotationX);
305 mTransformCamera->rotateY(mRotationY);
306 mTransformCamera->rotateZ(-mRotation);
307 mTransformCamera->getMatrix(mTransformMatrix3D);
308 mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
309 mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
310 mPivotY + mTranslationY);
311 mTransformMatrix->postConcat(*mTransformMatrix3D);
312 mTransformCamera->restore();
313 }
314 }
315 mMatrixDirty = false;
316 }
317}
318
Chris Craik2af46352012-11-26 18:30:17 -0800319void DisplayList::outputViewProperties(uint32_t level) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700320 updateMatrix();
321 if (mLeft != 0 || mTop != 0) {
Chris Craik2af46352012-11-26 18:30:17 -0800322 ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
Chet Haase1271e2c2012-04-20 09:54:27 -0700323 }
324 if (mStaticMatrix) {
Chris Craik2af46352012-11-26 18:30:17 -0800325 ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
326 level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
Chet Haase1271e2c2012-04-20 09:54:27 -0700327 }
328 if (mAnimationMatrix) {
Chris Craik2af46352012-11-26 18:30:17 -0800329 ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
330 level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
Chet Haase1271e2c2012-04-20 09:54:27 -0700331 }
332 if (mMatrixFlags != 0) {
333 if (mMatrixFlags == TRANSLATION) {
Chris Craik2af46352012-11-26 18:30:17 -0800334 ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
Chet Haase1271e2c2012-04-20 09:54:27 -0700335 } else {
Chris Craik2af46352012-11-26 18:30:17 -0800336 ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
337 level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
Chet Haase9420abd2012-03-29 16:28:32 -0700338 }
Chet Haase1271e2c2012-04-20 09:54:27 -0700339 }
340 if (mAlpha < 1 && !mCaching) {
Chet Haase3561d062012-10-23 12:54:51 -0700341 if (!mHasOverlappingRendering) {
Chris Craik2af46352012-11-26 18:30:17 -0800342 ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha);
Chet Haase3561d062012-10-23 12:54:51 -0700343 } else {
344 int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
345 if (mClipChildren) {
346 flags |= SkCanvas::kClipToLayer_SaveFlag;
347 }
Chris Craik2af46352012-11-26 18:30:17 -0800348 ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
Chet Haase3561d062012-10-23 12:54:51 -0700349 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
350 mMultipliedAlpha, flags);
Chet Haasea1cff502012-02-21 13:43:44 -0800351 }
Chet Haase1271e2c2012-04-20 09:54:27 -0700352 }
Romain Guy63696bf2013-02-07 15:20:55 -0800353 if (mClipChildren && !mCaching) {
Chris Craik2af46352012-11-26 18:30:17 -0800354 ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
Chet Haase1271e2c2012-04-20 09:54:27 -0700355 (float) mRight - mLeft, (float) mBottom - mTop);
Chet Haasea1cff502012-02-21 13:43:44 -0800356 }
357}
358
Chet Haase1271e2c2012-04-20 09:54:27 -0700359void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
Chris Craik2af46352012-11-26 18:30:17 -0800360#if DEBUG_DISPLAYLIST
361 outputViewProperties(level);
Chet Haasea1cff502012-02-21 13:43:44 -0800362#endif
Chet Haase1271e2c2012-04-20 09:54:27 -0700363 updateMatrix();
364 if (mLeft != 0 || mTop != 0) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700365 renderer.translate(mLeft, mTop);
366 }
367 if (mStaticMatrix) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700368 renderer.concatMatrix(mStaticMatrix);
369 } else if (mAnimationMatrix) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700370 renderer.concatMatrix(mAnimationMatrix);
371 }
372 if (mMatrixFlags != 0) {
373 if (mMatrixFlags == TRANSLATION) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700374 renderer.translate(mTranslationX, mTranslationY);
375 } else {
Chet Haase1271e2c2012-04-20 09:54:27 -0700376 renderer.concatMatrix(mTransformMatrix);
Chet Haasea1cff502012-02-21 13:43:44 -0800377 }
Chet Haase1271e2c2012-04-20 09:54:27 -0700378 }
379 if (mAlpha < 1 && !mCaching) {
380 if (!mHasOverlappingRendering) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700381 renderer.setAlpha(mAlpha);
382 } else {
383 // TODO: should be able to store the size of a DL at record time and not
384 // have to pass it into this call. In fact, this information might be in the
385 // location/size info that we store with the new native transform data.
386 int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
387 if (mClipChildren) {
388 flags |= SkCanvas::kClipToLayer_SaveFlag;
Chet Haasea1cff502012-02-21 13:43:44 -0800389 }
Chet Haase1271e2c2012-04-20 09:54:27 -0700390 renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
391 mMultipliedAlpha, flags);
Chet Haasea1cff502012-02-21 13:43:44 -0800392 }
Chet Haase1271e2c2012-04-20 09:54:27 -0700393 }
Romain Guy63696bf2013-02-07 15:20:55 -0800394 if (mClipChildren && !mCaching) {
Chet Haase1271e2c2012-04-20 09:54:27 -0700395 renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
396 SkRegion::kIntersect_Op);
Chet Haasea1cff502012-02-21 13:43:44 -0800397 }
398}
399
Chet Haase1271e2c2012-04-20 09:54:27 -0700400status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
Chet Haase48659092012-05-31 15:21:51 -0700401 status_t drawGlStatus = DrawGlInfo::kStatusDone;
Romain Guyb051e892010-09-28 19:09:36 -0700402
Romain Guyffac7fc2011-01-13 17:21:49 -0800403#if DEBUG_DISPLAY_LIST
Chet Haasea23eed82012-04-12 15:19:04 -0700404 Rect* clipRect = renderer.getClipRect();
Chris Craik2af46352012-11-26 18:30:17 -0800405 DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
406 (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top,
Chet Haasea23eed82012-04-12 15:19:04 -0700407 clipRect->right, clipRect->bottom);
Romain Guyffac7fc2011-01-13 17:21:49 -0800408#endif
Romain Guyb051e892010-09-28 19:09:36 -0700409
Romain Guy13631f32012-01-30 17:41:55 -0800410 renderer.startMark(mName.string());
Romain Guy8a4ac612012-07-17 17:32:48 -0700411
Chet Haase1271e2c2012-04-20 09:54:27 -0700412 int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
Chris Craik2af46352012-11-26 18:30:17 -0800413 DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
Chet Haase1271e2c2012-04-20 09:54:27 -0700414 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
415 setViewProperties(renderer, level);
Romain Guy8a4ac612012-07-17 17:32:48 -0700416
417 if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
Chris Craik2af46352012-11-26 18:30:17 -0800418 DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
Chet Haaseb85967b2012-03-26 14:37:51 -0700419 renderer.restoreToCount(restoreTo);
420 renderer.endMark();
Chet Haase48659092012-05-31 15:21:51 -0700421 return drawGlStatus;
Chet Haaseb85967b2012-03-26 14:37:51 -0700422 }
Romain Guy13631f32012-01-30 17:41:55 -0800423
Chet Haase9c1e23b2011-03-24 10:51:31 -0700424 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
Romain Guyffac7fc2011-01-13 17:21:49 -0800425 int saveCount = renderer.getSaveCount() - 1;
Chris Craik2af46352012-11-26 18:30:17 -0800426 for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
427 DisplayListOp *op = mDisplayListData->displayListOps[i];
Romain Guy8a4ac612012-07-17 17:32:48 -0700428#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
Chris Craik2af46352012-11-26 18:30:17 -0800429 Caches::getInstance().eventMark(strlen(op->name()), op->name());
Romain Guy8a4ac612012-07-17 17:32:48 -0700430#endif
431
Chris Craik2af46352012-11-26 18:30:17 -0800432 drawGlStatus |= op->replay(renderer, dirty, flags,
433 saveCount, level, mCaching, mMultipliedAlpha);
434 logBuffer.writeCommand(level, op->name());
Romain Guyb051e892010-09-28 19:09:36 -0700435 }
Romain Guyffac7fc2011-01-13 17:21:49 -0800436
Chris Craik2af46352012-11-26 18:30:17 -0800437 DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
Chet Haase1271e2c2012-04-20 09:54:27 -0700438 renderer.restoreToCount(restoreTo);
Romain Guy13631f32012-01-30 17:41:55 -0800439 renderer.endMark();
440
Chris Craik2af46352012-11-26 18:30:17 -0800441 DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(),
Romain Guy65549432012-03-26 16:45:05 -0700442 drawGlStatus);
443 return drawGlStatus;
Romain Guyb051e892010-09-28 19:09:36 -0700444}
445
446///////////////////////////////////////////////////////////////////////////////
Romain Guy4aa90572010-09-26 18:40:37 -0700447// Base structure
448///////////////////////////////////////////////////////////////////////////////
449
Romain Guy58ecc202012-09-07 11:58:36 -0700450DisplayListRenderer::DisplayListRenderer():
Chris Craik2af46352012-11-26 18:30:17 -0800451 mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
Romain Guy54c1a642012-09-27 17:55:46 -0700452 mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
453 mHasDrawOps(false), mFunctorCount(0) {
Romain Guy4aa90572010-09-26 18:40:37 -0700454}
455
456DisplayListRenderer::~DisplayListRenderer() {
457 reset();
458}
459
460void DisplayListRenderer::reset() {
Chris Craik2af46352012-11-26 18:30:17 -0800461 mDisplayListData = new DisplayListData();
Romain Guy58ecc202012-09-07 11:58:36 -0700462 mCaches.resourceCache.lock();
463
Chet Haase5c13d892010-10-08 08:37:55 -0700464 for (size_t i = 0; i < mBitmapResources.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700465 mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
Chet Haase5c13d892010-10-08 08:37:55 -0700466 }
Chet Haased98aa2d2010-10-25 15:47:32 -0700467
Romain Guy49c5fc02012-05-15 11:10:01 -0700468 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700469 mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
Romain Guy49c5fc02012-05-15 11:10:01 -0700470 }
Romain Guy49c5fc02012-05-15 11:10:01 -0700471
Romain Guyd586ad92011-06-22 16:14:36 -0700472 for (size_t i = 0; i < mFilterResources.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700473 mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
Romain Guyd586ad92011-06-22 16:14:36 -0700474 }
Romain Guyd586ad92011-06-22 16:14:36 -0700475
Romain Guy43ccf462011-01-14 18:51:01 -0800476 for (size_t i = 0; i < mShaders.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700477 mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
Romain Guy43ccf462011-01-14 18:51:01 -0800478 }
Romain Guy43ccf462011-01-14 18:51:01 -0800479
Chet Haased34dd712012-05-02 18:50:34 -0700480 for (size_t i = 0; i < mSourcePaths.size(); i++) {
Romain Guy58ecc202012-09-07 11:58:36 -0700481 mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
Chet Haased34dd712012-05-02 18:50:34 -0700482 }
Romain Guy58ecc202012-09-07 11:58:36 -0700483
Chet Haase603f6de2012-09-14 15:31:25 -0700484 for (size_t i = 0; i < mLayers.size(); i++) {
485 mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
486 }
487
Romain Guy58ecc202012-09-07 11:58:36 -0700488 mCaches.resourceCache.unlock();
489
490 mBitmapResources.clear();
491 mOwnedBitmapResources.clear();
492 mFilterResources.clear();
Chet Haased34dd712012-05-02 18:50:34 -0700493 mSourcePaths.clear();
494
Romain Guy58ecc202012-09-07 11:58:36 -0700495 mShaders.clear();
496 mShaderMap.clear();
497
Romain Guy43ccf462011-01-14 18:51:01 -0800498 mPaints.clear();
499 mPaintMap.clear();
Romain Guyd586ad92011-06-22 16:14:36 -0700500
Romain Guy735738c2012-12-03 12:34:51 -0800501 mRegions.clear();
502 mRegionMap.clear();
503
Romain Guy2fc941e2011-02-03 15:06:05 -0800504 mPaths.clear();
505 mPathMap.clear();
Romain Guyd586ad92011-06-22 16:14:36 -0700506
Chet Haased98aa2d2010-10-25 15:47:32 -0700507 mMatrices.clear();
Romain Guy04c9d8c2011-08-25 14:01:48 -0700508
Chet Haase603f6de2012-09-14 15:31:25 -0700509 mLayers.clear();
510
Romain Guy04c9d8c2011-08-25 14:01:48 -0700511 mHasDrawOps = false;
Romain Guy54c1a642012-09-27 17:55:46 -0700512 mFunctorCount = 0;
Romain Guy4aa90572010-09-26 18:40:37 -0700513}
514
515///////////////////////////////////////////////////////////////////////////////
516// Operations
517///////////////////////////////////////////////////////////////////////////////
518
Jeff Brown162a0212011-07-21 17:02:54 -0700519DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
520 if (!displayList) {
521 displayList = new DisplayList(*this);
Chet Haase5977baa2011-01-05 18:01:22 -0800522 } else {
Jeff Brown162a0212011-07-21 17:02:54 -0700523 displayList->initFromDisplayListRenderer(*this, true);
Chet Haase5977baa2011-01-05 18:01:22 -0800524 }
Romain Guy04c9d8c2011-08-25 14:01:48 -0700525 displayList->setRenderable(mHasDrawOps);
Jeff Brown162a0212011-07-21 17:02:54 -0700526 return displayList;
Chet Haase5977baa2011-01-05 18:01:22 -0800527}
528
Romain Guy49c5fc02012-05-15 11:10:01 -0700529bool DisplayListRenderer::isDeferred() {
530 return true;
531}
532
Romain Guyb051e892010-09-28 19:09:36 -0700533void DisplayListRenderer::setViewport(int width, int height) {
534 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
535
536 mWidth = width;
537 mHeight = height;
538}
539
Romain Guy7c25aab2012-10-18 15:05:02 -0700540status_t DisplayListRenderer::prepareDirty(float left, float top,
Romain Guy7d7b5492011-01-24 16:33:45 -0800541 float right, float bottom, bool opaque) {
Romain Guyb051e892010-09-28 19:09:36 -0700542 mSnapshot = new Snapshot(mFirstSnapshot,
543 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
544 mSaveCount = 1;
Romain Guy45e4c3d2012-09-11 17:17:07 -0700545
Romain Guyb051e892010-09-28 19:09:36 -0700546 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
Romain Guy45e4c3d2012-09-11 17:17:07 -0700547 mDirtyClip = opaque;
548
Romain Guy27454a42011-01-23 12:01:41 -0800549 mRestoreSaveCount = -1;
Romain Guy45e4c3d2012-09-11 17:17:07 -0700550
Chet Haase44b2fe32012-06-06 19:03:58 -0700551 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
Romain Guy27454a42011-01-23 12:01:41 -0800552}
553
554void DisplayListRenderer::finish() {
555 insertRestoreToCount();
Chris Craik2af46352012-11-26 18:30:17 -0800556 insertTranslate();
Romain Guyb051e892010-09-28 19:09:36 -0700557}
558
Chet Haasedaf98e92011-01-10 14:10:36 -0800559void DisplayListRenderer::interrupt() {
Chet Haasedaf98e92011-01-10 14:10:36 -0800560}
Romain Guy2b1847e2011-01-26 13:43:01 -0800561
Chet Haasedaf98e92011-01-10 14:10:36 -0800562void DisplayListRenderer::resume() {
Romain Guy4aa90572010-09-26 18:40:37 -0700563}
564
Romain Guy65549432012-03-26 16:45:05 -0700565status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
Romain Guycabfcc12011-03-07 18:06:46 -0800566 // Ignore dirty during recording, it matters only when we replay
Chris Craik2af46352012-11-26 18:30:17 -0800567 addDrawOp(new (alloc()) DrawFunctorOp(functor));
Romain Guy54c1a642012-09-27 17:55:46 -0700568 mFunctorCount++;
Romain Guy65549432012-03-26 16:45:05 -0700569 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
Chet Haasedaf98e92011-01-10 14:10:36 -0800570}
571
Romain Guy4aa90572010-09-26 18:40:37 -0700572int DisplayListRenderer::save(int flags) {
Chris Craik2af46352012-11-26 18:30:17 -0800573 addStateOp(new (alloc()) SaveOp(flags));
Romain Guy4aa90572010-09-26 18:40:37 -0700574 return OpenGLRenderer::save(flags);
575}
576
577void DisplayListRenderer::restore() {
Romain Guy04c9d8c2011-08-25 14:01:48 -0700578 if (mRestoreSaveCount < 0) {
Romain Guy33f6beb2012-02-16 19:24:51 -0800579 restoreToCount(getSaveCount() - 1);
580 return;
Romain Guy04c9d8c2011-08-25 14:01:48 -0700581 }
Romain Guy33f6beb2012-02-16 19:24:51 -0800582
583 mRestoreSaveCount--;
Chris Craik2af46352012-11-26 18:30:17 -0800584 insertTranslate();
Romain Guy4aa90572010-09-26 18:40:37 -0700585 OpenGLRenderer::restore();
586}
587
588void DisplayListRenderer::restoreToCount(int saveCount) {
Romain Guy27454a42011-01-23 12:01:41 -0800589 mRestoreSaveCount = saveCount;
Chris Craik2af46352012-11-26 18:30:17 -0800590 insertTranslate();
Romain Guy4aa90572010-09-26 18:40:37 -0700591 OpenGLRenderer::restoreToCount(saveCount);
592}
593
594int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
Chet Haase5c13d892010-10-08 08:37:55 -0700595 SkPaint* p, int flags) {
Chris Craik2af46352012-11-26 18:30:17 -0800596 addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, p, flags));
Romain Guyb051e892010-09-28 19:09:36 -0700597 return OpenGLRenderer::save(flags);
Romain Guy4aa90572010-09-26 18:40:37 -0700598}
599
Romain Guy5b3b3522010-10-27 18:57:51 -0700600int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
601 int alpha, int flags) {
Chris Craik2af46352012-11-26 18:30:17 -0800602 addStateOp(new (alloc()) SaveLayerAlphaOp(left, top, right, bottom, alpha, flags));
Romain Guy5b3b3522010-10-27 18:57:51 -0700603 return OpenGLRenderer::save(flags);
604}
605
Romain Guy4aa90572010-09-26 18:40:37 -0700606void DisplayListRenderer::translate(float dx, float dy) {
Romain Guy33f6beb2012-02-16 19:24:51 -0800607 mHasTranslate = true;
608 mTranslateX += dx;
609 mTranslateY += dy;
610 insertRestoreToCount();
Romain Guy4aa90572010-09-26 18:40:37 -0700611 OpenGLRenderer::translate(dx, dy);
612}
613
614void DisplayListRenderer::rotate(float degrees) {
Chris Craik2af46352012-11-26 18:30:17 -0800615 addStateOp(new (alloc()) RotateOp(degrees));
Romain Guy4aa90572010-09-26 18:40:37 -0700616 OpenGLRenderer::rotate(degrees);
617}
618
619void DisplayListRenderer::scale(float sx, float sy) {
Chris Craik2af46352012-11-26 18:30:17 -0800620 addStateOp(new (alloc()) ScaleOp(sx, sy));
Romain Guy4aa90572010-09-26 18:40:37 -0700621 OpenGLRenderer::scale(sx, sy);
622}
623
Romain Guy807daf72011-01-18 11:19:19 -0800624void DisplayListRenderer::skew(float sx, float sy) {
Chris Craik2af46352012-11-26 18:30:17 -0800625 addStateOp(new (alloc()) SkewOp(sx, sy));
Romain Guy807daf72011-01-18 11:19:19 -0800626 OpenGLRenderer::skew(sx, sy);
627}
628
Romain Guy4aa90572010-09-26 18:40:37 -0700629void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
Chris Craik2af46352012-11-26 18:30:17 -0800630 matrix = refMatrix(matrix);
631 addStateOp(new (alloc()) SetMatrixOp(matrix));
Romain Guy4aa90572010-09-26 18:40:37 -0700632 OpenGLRenderer::setMatrix(matrix);
633}
634
635void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
Chris Craik2af46352012-11-26 18:30:17 -0800636 matrix = refMatrix(matrix);
637 addStateOp(new (alloc()) ConcatMatrixOp(matrix));
Romain Guy4aa90572010-09-26 18:40:37 -0700638 OpenGLRenderer::concatMatrix(matrix);
639}
640
641bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
642 SkRegion::Op op) {
Chris Craik2af46352012-11-26 18:30:17 -0800643 addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
Romain Guy4aa90572010-09-26 18:40:37 -0700644 return OpenGLRenderer::clipRect(left, top, right, bottom, op);
645}
646
Romain Guy735738c2012-12-03 12:34:51 -0800647bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
Chris Craik2af46352012-11-26 18:30:17 -0800648 path = refPath(path);
649 addStateOp(new (alloc()) ClipPathOp(path, op));
Romain Guy735738c2012-12-03 12:34:51 -0800650 return OpenGLRenderer::clipPath(path, op);
651}
652
653bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
Chris Craik2af46352012-11-26 18:30:17 -0800654 region = refRegion(region);
655 addStateOp(new (alloc()) ClipRegionOp(region, op));
Romain Guy735738c2012-12-03 12:34:51 -0800656 return OpenGLRenderer::clipRegion(region, op);
657}
658
Romain Guy65549432012-03-26 16:45:05 -0700659status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
Chet Haase1271e2c2012-04-20 09:54:27 -0700660 Rect& dirty, int32_t flags, uint32_t level) {
Romain Guycabfcc12011-03-07 18:06:46 -0800661 // dirty is an out parameter and should not be recorded,
662 // it matters only when replaying the display list
Chet Haaseb85967b2012-03-26 14:37:51 -0700663
Chris Craik2af46352012-11-26 18:30:17 -0800664 // TODO: To be safe, the display list should be ref-counted in the
665 // resources cache, but we rely on the caller (UI toolkit) to
666 // do the right thing for now
667
668 addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags));
Romain Guy65549432012-03-26 16:45:05 -0700669 return DrawGlInfo::kStatusDone;
Romain Guy0fe478e2010-11-08 12:08:41 -0800670}
671
Chet Haase48659092012-05-31 15:21:51 -0700672status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800673 mLayers.add(layer);
674 mCaches.resourceCache.incrementRefcount(layer);
675 paint = refPaint(paint);
676
677 addDrawOp(new (alloc()) DrawLayerOp(layer, x, y, paint));
Chet Haase48659092012-05-31 15:21:51 -0700678 return DrawGlInfo::kStatusDone;
Romain Guy6c319ca2011-01-11 14:29:25 -0800679}
680
Chet Haase48659092012-05-31 15:21:51 -0700681status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800682 bitmap = refBitmap(bitmap);
683 paint = refPaint(paint);
684
685 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
Chet Haase48659092012-05-31 15:21:51 -0700686 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700687}
688
Chet Haase48659092012-05-31 15:21:51 -0700689status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800690 bitmap = refBitmap(bitmap);
691 matrix = refMatrix(matrix);
692 paint = refPaint(paint);
Romain Guy33f6beb2012-02-16 19:24:51 -0800693
Chris Craik2af46352012-11-26 18:30:17 -0800694 addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
Chet Haase48659092012-05-31 15:21:51 -0700695 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700696}
697
Chet Haase48659092012-05-31 15:21:51 -0700698status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
Romain Guy4aa90572010-09-26 18:40:37 -0700699 float srcRight, float srcBottom, float dstLeft, float dstTop,
Chet Haase5c13d892010-10-08 08:37:55 -0700700 float dstRight, float dstBottom, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800701 bitmap = refBitmap(bitmap);
702 paint = refPaint(paint);
703
704 addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
705 srcLeft, srcTop, srcRight, srcBottom,
706 dstLeft, dstTop, dstRight, dstBottom, paint));
Chet Haase48659092012-05-31 15:21:51 -0700707 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700708}
709
Chet Haase48659092012-05-31 15:21:51 -0700710status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
711 SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800712 bitmap = refBitmapData(bitmap);
713 paint = refPaint(paint);
714
715 addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
Chet Haase48659092012-05-31 15:21:51 -0700716 return DrawGlInfo::kStatusDone;
Romain Guye651cc62012-05-14 19:44:40 -0700717}
718
Chet Haase48659092012-05-31 15:21:51 -0700719status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
Romain Guy5a7b4662011-01-20 19:09:30 -0800720 float* vertices, int* colors, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800721 int count = (meshWidth + 1) * (meshHeight + 1) * 2;
722 bitmap = refBitmap(bitmap);
723 vertices = refBuffer<float>(vertices, count);
724 paint = refPaint(paint);
725 colors = refBuffer<int>(colors, count);
726
727 addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
728 vertices, colors, paint));
Chet Haase48659092012-05-31 15:21:51 -0700729 return DrawGlInfo::kStatusDone;
Romain Guy5a7b4662011-01-20 19:09:30 -0800730}
731
Chet Haase48659092012-05-31 15:21:51 -0700732status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
733 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
734 int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
Romain Guybe6f9dc2012-07-16 12:41:17 -0700735 int alpha;
736 SkXfermode::Mode mode;
737 OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
738
Chris Craik2af46352012-11-26 18:30:17 -0800739 bitmap = refBitmap(bitmap);
740 xDivs = refBuffer<int>(xDivs, width);
741 yDivs = refBuffer<int>(yDivs, height);
742 colors = refBuffer<uint32_t>(colors, numColors);
743
744 addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors,
745 left, top, right, bottom, alpha, mode));
Chet Haase48659092012-05-31 15:21:51 -0700746 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700747}
748
Chet Haase48659092012-05-31 15:21:51 -0700749status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
Chris Craik2af46352012-11-26 18:30:17 -0800750 addDrawOp(new (alloc()) DrawColorOp(color, mode));
Chet Haase48659092012-05-31 15:21:51 -0700751 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700752}
753
Chet Haase48659092012-05-31 15:21:51 -0700754status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
Chet Haase5c13d892010-10-08 08:37:55 -0700755 SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800756 paint = refPaint(paint);
757 addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
Chet Haase48659092012-05-31 15:21:51 -0700758 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700759}
760
Chet Haase48659092012-05-31 15:21:51 -0700761status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
Chet Haasea1cff502012-02-21 13:43:44 -0800762 float rx, float ry, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800763 paint = refPaint(paint);
764 addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
Chet Haase48659092012-05-31 15:21:51 -0700765 return DrawGlInfo::kStatusDone;
Romain Guy01d58e42011-01-19 21:54:02 -0800766}
767
Chet Haase48659092012-05-31 15:21:51 -0700768status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800769 paint = refPaint(paint);
770 addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
Chet Haase48659092012-05-31 15:21:51 -0700771 return DrawGlInfo::kStatusDone;
Romain Guy01d58e42011-01-19 21:54:02 -0800772}
773
Chet Haase48659092012-05-31 15:21:51 -0700774status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800775 SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800776 paint = refPaint(paint);
777 addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
Chet Haase48659092012-05-31 15:21:51 -0700778 return DrawGlInfo::kStatusDone;
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800779}
780
Chet Haase48659092012-05-31 15:21:51 -0700781status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
Romain Guy8b2f5262011-01-23 16:15:02 -0800782 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800783 paint = refPaint(paint);
784 addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
785 startAngle, sweepAngle, useCenter, paint));
Chet Haase48659092012-05-31 15:21:51 -0700786 return DrawGlInfo::kStatusDone;
Romain Guy8b2f5262011-01-23 16:15:02 -0800787}
788
Chet Haase48659092012-05-31 15:21:51 -0700789status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800790 path = refPath(path);
791 paint = refPaint(paint);
Romain Guy33f6beb2012-02-16 19:24:51 -0800792
Chris Craik2af46352012-11-26 18:30:17 -0800793 addDrawOp(new (alloc()) DrawPathOp(path, paint));
Chet Haase48659092012-05-31 15:21:51 -0700794 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700795}
796
Chet Haase48659092012-05-31 15:21:51 -0700797status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800798 points = refBuffer<float>(points, count);
799 paint = refPaint(paint);
800
801 addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
Chet Haase48659092012-05-31 15:21:51 -0700802 return DrawGlInfo::kStatusDone;
Romain Guy4aa90572010-09-26 18:40:37 -0700803}
804
Chet Haase48659092012-05-31 15:21:51 -0700805status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
Chris Craik2af46352012-11-26 18:30:17 -0800806 points = refBuffer<float>(points, count);
807 paint = refPaint(paint);
808
809 addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
Chet Haase48659092012-05-31 15:21:51 -0700810 return DrawGlInfo::kStatusDone;
Romain Guyed6fcb02011-03-21 13:11:28 -0700811}
812
Chet Haase48659092012-05-31 15:21:51 -0700813status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
Romain Guy325740f2012-02-24 16:48:34 -0800814 SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
Chet Haase48659092012-05-31 15:21:51 -0700815 if (!text || count <= 0) return DrawGlInfo::kStatusDone;
Chris Craik2af46352012-11-26 18:30:17 -0800816
Chris Craik2af46352012-11-26 18:30:17 -0800817 text = refText(text, bytesCount);
818 path = refPath(path);
819 paint = refPaint(paint);
820
821 DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
822 hOffset, vOffset, paint);
823 if (addDrawOp(op)) {
824 // precache if draw operation is visible
825 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
826 fontRenderer.precache(paint, text, count, *mSnapshot->transform);
827 }
Chet Haase48659092012-05-31 15:21:51 -0700828 return DrawGlInfo::kStatusDone;
Romain Guy325740f2012-02-24 16:48:34 -0800829}
830
Chet Haase48659092012-05-31 15:21:51 -0700831status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
Romain Guyeb9a5362012-01-17 17:39:26 -0800832 const float* positions, SkPaint* paint) {
Chet Haase48659092012-05-31 15:21:51 -0700833 if (!text || count <= 0) return DrawGlInfo::kStatusDone;
Chris Craik2af46352012-11-26 18:30:17 -0800834
Chris Craik2af46352012-11-26 18:30:17 -0800835 text = refText(text, bytesCount);
836 positions = refBuffer<float>(positions, count * 2);
837 paint = refPaint(paint);
838
839 DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
840 if (addDrawOp(op)) {
841 // precache if draw operation is visible
842 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
843 fontRenderer.precache(paint, text, count, *mSnapshot->transform);
844 }
Chet Haase48659092012-05-31 15:21:51 -0700845 return DrawGlInfo::kStatusDone;
Romain Guyeb9a5362012-01-17 17:39:26 -0800846}
847
Romain Guyc2525952012-07-27 16:41:22 -0700848status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
Raph Levien996e57c2012-07-23 15:22:52 -0700849 float x, float y, const float* positions, SkPaint* paint, float length) {
850 if (!text || count <= 0) return DrawGlInfo::kStatusDone;
851
Raph Levien996e57c2012-07-23 15:22:52 -0700852 if (length < 0.0f) length = paint->measureText(text, bytesCount);
853
Chris Craik2af46352012-11-26 18:30:17 -0800854 text = refText(text, bytesCount);
855 positions = refBuffer<float>(positions, count * 2);
856 paint = refPaint(paint);
Raph Levien996e57c2012-07-23 15:22:52 -0700857
Chris Craik2af46352012-11-26 18:30:17 -0800858 DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
859 if (addDrawOp(op)) {
860 // precache if draw operation is visible
861 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
862 fontRenderer.precache(paint, text, count, *mSnapshot->transform);
Chet Haasee816bae2012-08-09 13:39:02 -0700863 }
Raph Levien996e57c2012-07-23 15:22:52 -0700864 return DrawGlInfo::kStatusDone;
865}
866
Romain Guy672433d2013-01-04 19:05:13 -0800867status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
868 if (count <= 0) return DrawGlInfo::kStatusDone;
869
Chris Craik2af46352012-11-26 18:30:17 -0800870 rects = refBuffer<float>(rects, count);
871 paint = refPaint(paint);
872 addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
Romain Guy672433d2013-01-04 19:05:13 -0800873 return DrawGlInfo::kStatusDone;
874}
875
Romain Guy4aa90572010-09-26 18:40:37 -0700876void DisplayListRenderer::resetShader() {
Chris Craik2af46352012-11-26 18:30:17 -0800877 addStateOp(new (alloc()) ResetShaderOp());
Romain Guy4aa90572010-09-26 18:40:37 -0700878}
879
880void DisplayListRenderer::setupShader(SkiaShader* shader) {
Chris Craik2af46352012-11-26 18:30:17 -0800881 shader = refShader(shader);
882 addStateOp(new (alloc()) SetupShaderOp(shader));
Romain Guy4aa90572010-09-26 18:40:37 -0700883}
884
885void DisplayListRenderer::resetColorFilter() {
Chris Craik2af46352012-11-26 18:30:17 -0800886 addStateOp(new (alloc()) ResetColorFilterOp());
Romain Guy4aa90572010-09-26 18:40:37 -0700887}
888
889void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
Chris Craik2af46352012-11-26 18:30:17 -0800890 filter = refColorFilter(filter);
891 addStateOp(new (alloc()) SetupColorFilterOp(filter));
Romain Guy4aa90572010-09-26 18:40:37 -0700892}
893
894void DisplayListRenderer::resetShadow() {
Chris Craik2af46352012-11-26 18:30:17 -0800895 addStateOp(new (alloc()) ResetShadowOp());
Romain Guy4aa90572010-09-26 18:40:37 -0700896}
897
898void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
Chris Craik2af46352012-11-26 18:30:17 -0800899 addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
Romain Guy4aa90572010-09-26 18:40:37 -0700900}
901
Romain Guy5ff9df62012-01-23 17:09:05 -0800902void DisplayListRenderer::resetPaintFilter() {
Chris Craik2af46352012-11-26 18:30:17 -0800903 addStateOp(new (alloc()) ResetPaintFilterOp());
Romain Guy5ff9df62012-01-23 17:09:05 -0800904}
905
906void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
Chris Craik2af46352012-11-26 18:30:17 -0800907 addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
908}
909
910void DisplayListRenderer::insertRestoreToCount() {
911 if (mRestoreSaveCount >= 0) {
912 DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount);
913 mDisplayListData->displayListOps.add(op);
914 mRestoreSaveCount = -1;
915 }
916}
917
918void DisplayListRenderer::insertTranslate() {
919 if (mHasTranslate) {
920 if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
921 DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY);
922 mDisplayListData->displayListOps.add(op);
923 mTranslateX = mTranslateY = 0.0f;
924 }
925 mHasTranslate = false;
926 }
927}
928
929void DisplayListRenderer::addStateOp(StateOp* op) {
930 addOpInternal(op);
931}
932
933bool DisplayListRenderer::addDrawOp(DrawOp* op) {
934 bool rejected = false;
935 Rect localBounds;
936 if (op->getLocalBounds(localBounds)) {
937 rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
938 localBounds.right, localBounds.bottom);
939 op->setQuickRejected(rejected);
940 }
941 mHasDrawOps = true;
942 addOpInternal(op);
943 return !rejected;
Romain Guy5ff9df62012-01-23 17:09:05 -0800944}
945
Romain Guy4aa90572010-09-26 18:40:37 -0700946}; // namespace uirenderer
947}; // namespace android