blob: 4d1fcb3af3d01f0e58cbec757a00cdf898de3af2 [file] [log] [blame]
Chris Craik0776a602013-02-14 15:36:01 -08001/*
2 * Copyright (C) 2013 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#ifndef ANDROID_HWUI_DISPLAY_LIST_H
18#define ANDROID_HWUI_DISPLAY_LIST_H
19
Romain Guy7031ff62013-02-22 11:48:16 -080020#ifndef LOG_TAG
21 #define LOG_TAG "OpenGLRenderer"
22#endif
23
Chris Craik0776a602013-02-14 15:36:01 -080024#include <SkCamera.h>
25#include <SkMatrix.h>
26
27#include <utils/RefBase.h>
28#include <utils/SortedVector.h>
29#include <utils/String8.h>
30#include <utils/Vector.h>
31#include <cutils/compiler.h>
32
33#include "utils/LinearAllocator.h"
34
35#include "Debug.h"
36
37#define TRANSLATION 0x0001
38#define ROTATION 0x0002
39#define ROTATION_3D 0x0004
40#define SCALE 0x0008
41#define PIVOT 0x0010
42
43class SkBitmap;
44class SkPaint;
45class SkPath;
46class SkRegion;
47
48namespace android {
49namespace uirenderer {
50
Chris Craikc3566d02013-02-04 16:16:33 -080051class DeferredDisplayList;
Chris Craik0776a602013-02-14 15:36:01 -080052class DisplayListOp;
53class DisplayListRenderer;
54class OpenGLRenderer;
55class Rect;
56class Layer;
57class SkiaColorFilter;
58class SkiaShader;
59
60/**
61 * Refcounted structure that holds data used in display list stream
62 */
63class DisplayListData: public LightRefBase<DisplayListData> {
64public:
65 LinearAllocator allocator;
66 Vector<DisplayListOp*> displayListOps;
67};
68
69/**
70 * Replays recorded drawing commands.
71 */
72class DisplayList {
73public:
74 DisplayList(const DisplayListRenderer& recorder);
75 ANDROID_API ~DisplayList();
76
77 // See flags defined in DisplayList.java
78 enum ReplayFlag {
79 kReplayFlag_ClipChildren = 0x1
80 };
81
82 void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
83 void outputViewProperties(uint32_t level);
84
85 ANDROID_API size_t getSize();
86 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
87 ANDROID_API static void outputLogBuffer(int fd);
88
89 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
90
Chris Craikc3566d02013-02-04 16:16:33 -080091 status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0,
92 DeferredDisplayList* deferredList = NULL);
Chris Craik0776a602013-02-14 15:36:01 -080093
94 void output(uint32_t level = 0);
95
96 ANDROID_API void reset();
97
98 void setRenderable(bool renderable) {
99 mIsRenderable = renderable;
100 }
101
102 bool isRenderable() const {
103 return mIsRenderable;
104 }
105
106 void setName(const char* name) {
107 if (name) {
108 mName.setTo(name);
109 }
110 }
111
Romain Guy52036b12013-02-14 18:03:37 -0800112 const char* getName() const {
113 return mName.string();
114 }
115
Chris Craik0776a602013-02-14 15:36:01 -0800116 void setClipChildren(bool clipChildren) {
117 mClipChildren = clipChildren;
118 }
119
120 void setStaticMatrix(SkMatrix* matrix) {
121 delete mStaticMatrix;
122 mStaticMatrix = new SkMatrix(*matrix);
123 }
124
Romain Guy52036b12013-02-14 18:03:37 -0800125 // Can return NULL
126 SkMatrix* getStaticMatrix() {
127 return mStaticMatrix;
128 }
129
Chris Craik0776a602013-02-14 15:36:01 -0800130 void setAnimationMatrix(SkMatrix* matrix) {
131 delete mAnimationMatrix;
132 if (matrix) {
133 mAnimationMatrix = new SkMatrix(*matrix);
134 } else {
135 mAnimationMatrix = NULL;
136 }
137 }
138
139 void setAlpha(float alpha) {
140 alpha = fminf(1.0f, fmaxf(0.0f, alpha));
141 if (alpha != mAlpha) {
142 mAlpha = alpha;
143 mMultipliedAlpha = (int) (255 * alpha);
144 }
145 }
146
Romain Guy52036b12013-02-14 18:03:37 -0800147 float getAlpha() const {
148 return mAlpha;
149 }
150
Chris Craik0776a602013-02-14 15:36:01 -0800151 void setHasOverlappingRendering(bool hasOverlappingRendering) {
152 mHasOverlappingRendering = hasOverlappingRendering;
153 }
154
Romain Guy52036b12013-02-14 18:03:37 -0800155 bool hasOverlappingRendering() const {
156 return mHasOverlappingRendering;
157 }
158
Chris Craik0776a602013-02-14 15:36:01 -0800159 void setTranslationX(float translationX) {
160 if (translationX != mTranslationX) {
161 mTranslationX = translationX;
162 mMatrixDirty = true;
163 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
164 mMatrixFlags &= ~TRANSLATION;
165 } else {
166 mMatrixFlags |= TRANSLATION;
167 }
168 }
169 }
170
Romain Guy52036b12013-02-14 18:03:37 -0800171 float getTranslationX() const {
172 return mTranslationX;
173 }
174
Chris Craik0776a602013-02-14 15:36:01 -0800175 void setTranslationY(float translationY) {
176 if (translationY != mTranslationY) {
177 mTranslationY = translationY;
178 mMatrixDirty = true;
179 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
180 mMatrixFlags &= ~TRANSLATION;
181 } else {
182 mMatrixFlags |= TRANSLATION;
183 }
184 }
185 }
186
Romain Guy52036b12013-02-14 18:03:37 -0800187 float getTranslationY() const {
188 return mTranslationY;
189 }
190
Chris Craik0776a602013-02-14 15:36:01 -0800191 void setRotation(float rotation) {
192 if (rotation != mRotation) {
193 mRotation = rotation;
194 mMatrixDirty = true;
195 if (mRotation == 0.0f) {
196 mMatrixFlags &= ~ROTATION;
197 } else {
198 mMatrixFlags |= ROTATION;
199 }
200 }
201 }
202
Romain Guy52036b12013-02-14 18:03:37 -0800203 float getRotation() const {
204 return mRotation;
205 }
206
Chris Craik0776a602013-02-14 15:36:01 -0800207 void setRotationX(float rotationX) {
208 if (rotationX != mRotationX) {
209 mRotationX = rotationX;
210 mMatrixDirty = true;
211 if (mRotationX == 0.0f && mRotationY == 0.0f) {
212 mMatrixFlags &= ~ROTATION_3D;
213 } else {
214 mMatrixFlags |= ROTATION_3D;
215 }
216 }
217 }
218
Romain Guy52036b12013-02-14 18:03:37 -0800219 float getRotationX() const {
220 return mRotationX;
221 }
222
Chris Craik0776a602013-02-14 15:36:01 -0800223 void setRotationY(float rotationY) {
224 if (rotationY != mRotationY) {
225 mRotationY = rotationY;
226 mMatrixDirty = true;
227 if (mRotationX == 0.0f && mRotationY == 0.0f) {
228 mMatrixFlags &= ~ROTATION_3D;
229 } else {
230 mMatrixFlags |= ROTATION_3D;
231 }
232 }
233 }
234
Romain Guy52036b12013-02-14 18:03:37 -0800235 float getRotationY() const {
236 return mRotationY;
237 }
238
Chris Craik0776a602013-02-14 15:36:01 -0800239 void setScaleX(float scaleX) {
240 if (scaleX != mScaleX) {
241 mScaleX = scaleX;
242 mMatrixDirty = true;
243 if (mScaleX == 1.0f && mScaleY == 1.0f) {
244 mMatrixFlags &= ~SCALE;
245 } else {
246 mMatrixFlags |= SCALE;
247 }
248 }
249 }
250
Romain Guy52036b12013-02-14 18:03:37 -0800251 float getScaleX() const {
252 return mScaleX;
253 }
254
Chris Craik0776a602013-02-14 15:36:01 -0800255 void setScaleY(float scaleY) {
256 if (scaleY != mScaleY) {
257 mScaleY = scaleY;
258 mMatrixDirty = true;
259 if (mScaleX == 1.0f && mScaleY == 1.0f) {
260 mMatrixFlags &= ~SCALE;
261 } else {
262 mMatrixFlags |= SCALE;
263 }
264 }
265 }
266
Romain Guy52036b12013-02-14 18:03:37 -0800267 float getScaleY() const {
268 return mScaleY;
269 }
270
Chris Craik0776a602013-02-14 15:36:01 -0800271 void setPivotX(float pivotX) {
272 mPivotX = pivotX;
273 mMatrixDirty = true;
274 if (mPivotX == 0.0f && mPivotY == 0.0f) {
275 mMatrixFlags &= ~PIVOT;
276 } else {
277 mMatrixFlags |= PIVOT;
278 }
279 mPivotExplicitlySet = true;
280 }
281
Romain Guy52036b12013-02-14 18:03:37 -0800282 ANDROID_API float getPivotX();
283
Chris Craik0776a602013-02-14 15:36:01 -0800284 void setPivotY(float pivotY) {
285 mPivotY = pivotY;
286 mMatrixDirty = true;
287 if (mPivotX == 0.0f && mPivotY == 0.0f) {
288 mMatrixFlags &= ~PIVOT;
289 } else {
290 mMatrixFlags |= PIVOT;
291 }
292 mPivotExplicitlySet = true;
293 }
294
Romain Guy52036b12013-02-14 18:03:37 -0800295 ANDROID_API float getPivotY();
296
Chris Craik0776a602013-02-14 15:36:01 -0800297 void setCameraDistance(float distance) {
298 if (distance != mCameraDistance) {
299 mCameraDistance = distance;
300 mMatrixDirty = true;
301 if (!mTransformCamera) {
302 mTransformCamera = new Sk3DView();
303 mTransformMatrix3D = new SkMatrix();
304 }
305 mTransformCamera->setCameraLocation(0, 0, distance);
306 }
307 }
308
Romain Guy52036b12013-02-14 18:03:37 -0800309 float getCameraDistance() const {
310 return mCameraDistance;
311 }
312
Chris Craik0776a602013-02-14 15:36:01 -0800313 void setLeft(int left) {
314 if (left != mLeft) {
315 mLeft = left;
316 mWidth = mRight - mLeft;
317 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
318 mMatrixDirty = true;
319 }
320 }
321 }
322
Romain Guy52036b12013-02-14 18:03:37 -0800323 float getLeft() const {
324 return mLeft;
325 }
326
Chris Craik0776a602013-02-14 15:36:01 -0800327 void setTop(int top) {
328 if (top != mTop) {
329 mTop = top;
330 mHeight = mBottom - mTop;
331 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
332 mMatrixDirty = true;
333 }
334 }
335 }
336
Romain Guy52036b12013-02-14 18:03:37 -0800337 float getTop() const {
338 return mTop;
339 }
340
Chris Craik0776a602013-02-14 15:36:01 -0800341 void setRight(int right) {
342 if (right != mRight) {
343 mRight = right;
344 mWidth = mRight - mLeft;
345 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
346 mMatrixDirty = true;
347 }
348 }
349 }
350
Romain Guy52036b12013-02-14 18:03:37 -0800351 float getRight() const {
352 return mRight;
353 }
354
Chris Craik0776a602013-02-14 15:36:01 -0800355 void setBottom(int bottom) {
356 if (bottom != mBottom) {
357 mBottom = bottom;
358 mHeight = mBottom - mTop;
359 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
360 mMatrixDirty = true;
361 }
362 }
363 }
364
Romain Guy52036b12013-02-14 18:03:37 -0800365 float getBottom() const {
366 return mBottom;
367 }
368
Chris Craik0776a602013-02-14 15:36:01 -0800369 void setLeftTop(int left, int top) {
370 if (left != mLeft || top != mTop) {
371 mLeft = left;
372 mTop = top;
373 mWidth = mRight - mLeft;
374 mHeight = mBottom - mTop;
375 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
376 mMatrixDirty = true;
377 }
378 }
379 }
380
381 void setLeftTopRightBottom(int left, int top, int right, int bottom) {
382 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
383 mLeft = left;
384 mTop = top;
385 mRight = right;
386 mBottom = bottom;
387 mWidth = mRight - mLeft;
388 mHeight = mBottom - mTop;
389 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
390 mMatrixDirty = true;
391 }
392 }
393 }
394
Romain Guy52036b12013-02-14 18:03:37 -0800395 void offsetLeftRight(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800396 if (offset != 0) {
397 mLeft += offset;
398 mRight += offset;
399 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
400 mMatrixDirty = true;
401 }
402 }
403 }
404
Romain Guy52036b12013-02-14 18:03:37 -0800405 void offsetTopBottom(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800406 if (offset != 0) {
407 mTop += offset;
408 mBottom += offset;
409 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
410 mMatrixDirty = true;
411 }
412 }
413 }
414
415 void setCaching(bool caching) {
416 mCaching = caching;
417 }
418
419 int getWidth() {
420 return mWidth;
421 }
422
423 int getHeight() {
424 return mHeight;
425 }
426
427private:
428 void init();
429
430 void clearResources();
431
432 void updateMatrix();
433
434 class TextContainer {
435 public:
436 size_t length() const {
437 return mByteLength;
438 }
439
440 const char* text() const {
441 return (const char*) mText;
442 }
443
444 size_t mByteLength;
445 const char* mText;
446 };
447
448 Vector<SkBitmap*> mBitmapResources;
449 Vector<SkBitmap*> mOwnedBitmapResources;
450 Vector<SkiaColorFilter*> mFilterResources;
451
452 Vector<SkPaint*> mPaints;
453 Vector<SkPath*> mPaths;
454 SortedVector<SkPath*> mSourcePaths;
455 Vector<SkRegion*> mRegions;
456 Vector<SkMatrix*> mMatrices;
457 Vector<SkiaShader*> mShaders;
458 Vector<Layer*> mLayers;
459
460 sp<DisplayListData> mDisplayListData;
461
462 size_t mSize;
463
464 bool mIsRenderable;
465 uint32_t mFunctorCount;
466
467 String8 mName;
468
469 // View properties
470 bool mClipChildren;
471 float mAlpha;
472 int mMultipliedAlpha;
473 bool mHasOverlappingRendering;
474 float mTranslationX, mTranslationY;
475 float mRotation, mRotationX, mRotationY;
476 float mScaleX, mScaleY;
477 float mPivotX, mPivotY;
478 float mCameraDistance;
479 int mLeft, mTop, mRight, mBottom;
480 int mWidth, mHeight;
481 int mPrevWidth, mPrevHeight;
482 bool mPivotExplicitlySet;
483 bool mMatrixDirty;
484 bool mMatrixIsIdentity;
485 uint32_t mMatrixFlags;
486 SkMatrix* mTransformMatrix;
487 Sk3DView* mTransformCamera;
488 SkMatrix* mTransformMatrix3D;
489 SkMatrix* mStaticMatrix;
490 SkMatrix* mAnimationMatrix;
491 bool mCaching;
492}; // class DisplayList
493
494}; // namespace uirenderer
495}; // namespace android
496
497#endif // ANDROID_HWUI_OPENGL_RENDERER_H