blob: 194be9e6cd91b01dbcffb6d274975b9c6c944063 [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
Chris Craikff785832013-03-08 13:12:16 -080027#include <private/hwui/DrawGlInfo.h>
28
Chris Craik0776a602013-02-14 15:36:01 -080029#include <utils/RefBase.h>
30#include <utils/SortedVector.h>
31#include <utils/String8.h>
32#include <utils/Vector.h>
Romain Guye3b0a012013-06-26 15:45:41 -070033
Chris Craik0776a602013-02-14 15:36:01 -080034#include <cutils/compiler.h>
35
Romain Guye3b0a012013-06-26 15:45:41 -070036#include <androidfw/ResourceTypes.h>
37
Chris Craik0776a602013-02-14 15:36:01 -080038#include "utils/LinearAllocator.h"
39
40#include "Debug.h"
41
42#define TRANSLATION 0x0001
43#define ROTATION 0x0002
44#define ROTATION_3D 0x0004
45#define SCALE 0x0008
46#define PIVOT 0x0010
47
48class SkBitmap;
49class SkPaint;
50class SkPath;
51class SkRegion;
52
53namespace android {
54namespace uirenderer {
55
Chris Craikc3566d02013-02-04 16:16:33 -080056class DeferredDisplayList;
Chris Craik0776a602013-02-14 15:36:01 -080057class DisplayListOp;
58class DisplayListRenderer;
59class OpenGLRenderer;
60class Rect;
61class Layer;
62class SkiaColorFilter;
63class SkiaShader;
64
Chris Craikff785832013-03-08 13:12:16 -080065class ClipRectOp;
66class SaveLayerOp;
67class SaveOp;
68class RestoreToCountOp;
69
70struct DeferStateStruct {
71 DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
72 : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {}
73 DeferredDisplayList& mDeferredList;
74 OpenGLRenderer& mRenderer;
75 const int mReplayFlags;
76};
77
78struct ReplayStateStruct {
79 ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
80 : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags),
81 mDrawGlStatus(DrawGlInfo::kStatusDone) {}
82 OpenGLRenderer& mRenderer;
83 Rect& mDirty;
84 const int mReplayFlags;
85 status_t mDrawGlStatus;
86};
87
Chris Craik0776a602013-02-14 15:36:01 -080088/**
89 * Refcounted structure that holds data used in display list stream
90 */
Chris Craikff785832013-03-08 13:12:16 -080091class DisplayListData : public LightRefBase<DisplayListData> {
Chris Craik0776a602013-02-14 15:36:01 -080092public:
93 LinearAllocator allocator;
94 Vector<DisplayListOp*> displayListOps;
95};
96
97/**
98 * Replays recorded drawing commands.
99 */
100class DisplayList {
101public:
102 DisplayList(const DisplayListRenderer& recorder);
103 ANDROID_API ~DisplayList();
104
105 // See flags defined in DisplayList.java
106 enum ReplayFlag {
107 kReplayFlag_ClipChildren = 0x1
108 };
109
Chris Craik0776a602013-02-14 15:36:01 -0800110
111 ANDROID_API size_t getSize();
112 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
113 ANDROID_API static void outputLogBuffer(int fd);
114
115 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
116
Chris Craikff785832013-03-08 13:12:16 -0800117
118 void defer(DeferStateStruct& deferStruct, const int level);
119 void replay(ReplayStateStruct& replayStruct, const int level);
Chris Craik0776a602013-02-14 15:36:01 -0800120
121 void output(uint32_t level = 0);
122
123 ANDROID_API void reset();
124
125 void setRenderable(bool renderable) {
126 mIsRenderable = renderable;
127 }
128
129 bool isRenderable() const {
130 return mIsRenderable;
131 }
132
133 void setName(const char* name) {
134 if (name) {
Romain Guy450dc752013-06-05 14:14:03 -0700135 char* lastPeriod = strrchr(name, '.');
136 if (lastPeriod) {
137 mName.setTo(lastPeriod + 1);
138 } else {
139 mName.setTo(name);
140 }
Chris Craik0776a602013-02-14 15:36:01 -0800141 }
142 }
143
Romain Guy52036b12013-02-14 18:03:37 -0800144 const char* getName() const {
145 return mName.string();
146 }
147
Chet Haasedd671592013-04-19 14:54:34 -0700148 void setClipToBounds(bool clipToBounds) {
149 mClipToBounds = clipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800150 }
151
152 void setStaticMatrix(SkMatrix* matrix) {
153 delete mStaticMatrix;
154 mStaticMatrix = new SkMatrix(*matrix);
155 }
156
Romain Guy52036b12013-02-14 18:03:37 -0800157 // Can return NULL
158 SkMatrix* getStaticMatrix() {
159 return mStaticMatrix;
160 }
161
Chris Craik0776a602013-02-14 15:36:01 -0800162 void setAnimationMatrix(SkMatrix* matrix) {
163 delete mAnimationMatrix;
164 if (matrix) {
165 mAnimationMatrix = new SkMatrix(*matrix);
166 } else {
167 mAnimationMatrix = NULL;
168 }
169 }
170
171 void setAlpha(float alpha) {
172 alpha = fminf(1.0f, fmaxf(0.0f, alpha));
173 if (alpha != mAlpha) {
174 mAlpha = alpha;
Chris Craik0776a602013-02-14 15:36:01 -0800175 }
176 }
177
Romain Guy52036b12013-02-14 18:03:37 -0800178 float getAlpha() const {
179 return mAlpha;
180 }
181
Chris Craik0776a602013-02-14 15:36:01 -0800182 void setHasOverlappingRendering(bool hasOverlappingRendering) {
183 mHasOverlappingRendering = hasOverlappingRendering;
184 }
185
Romain Guy52036b12013-02-14 18:03:37 -0800186 bool hasOverlappingRendering() const {
187 return mHasOverlappingRendering;
188 }
189
Chris Craik0776a602013-02-14 15:36:01 -0800190 void setTranslationX(float translationX) {
191 if (translationX != mTranslationX) {
192 mTranslationX = translationX;
193 mMatrixDirty = true;
194 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
195 mMatrixFlags &= ~TRANSLATION;
196 } else {
197 mMatrixFlags |= TRANSLATION;
198 }
199 }
200 }
201
Romain Guy52036b12013-02-14 18:03:37 -0800202 float getTranslationX() const {
203 return mTranslationX;
204 }
205
Chris Craik0776a602013-02-14 15:36:01 -0800206 void setTranslationY(float translationY) {
207 if (translationY != mTranslationY) {
208 mTranslationY = translationY;
209 mMatrixDirty = true;
210 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
211 mMatrixFlags &= ~TRANSLATION;
212 } else {
213 mMatrixFlags |= TRANSLATION;
214 }
215 }
216 }
217
Romain Guy52036b12013-02-14 18:03:37 -0800218 float getTranslationY() const {
219 return mTranslationY;
220 }
221
Chris Craik0776a602013-02-14 15:36:01 -0800222 void setRotation(float rotation) {
223 if (rotation != mRotation) {
224 mRotation = rotation;
225 mMatrixDirty = true;
226 if (mRotation == 0.0f) {
227 mMatrixFlags &= ~ROTATION;
228 } else {
229 mMatrixFlags |= ROTATION;
230 }
231 }
232 }
233
Romain Guy52036b12013-02-14 18:03:37 -0800234 float getRotation() const {
235 return mRotation;
236 }
237
Chris Craik0776a602013-02-14 15:36:01 -0800238 void setRotationX(float rotationX) {
239 if (rotationX != mRotationX) {
240 mRotationX = rotationX;
241 mMatrixDirty = true;
242 if (mRotationX == 0.0f && mRotationY == 0.0f) {
243 mMatrixFlags &= ~ROTATION_3D;
244 } else {
245 mMatrixFlags |= ROTATION_3D;
246 }
247 }
248 }
249
Romain Guy52036b12013-02-14 18:03:37 -0800250 float getRotationX() const {
251 return mRotationX;
252 }
253
Chris Craik0776a602013-02-14 15:36:01 -0800254 void setRotationY(float rotationY) {
255 if (rotationY != mRotationY) {
256 mRotationY = rotationY;
257 mMatrixDirty = true;
258 if (mRotationX == 0.0f && mRotationY == 0.0f) {
259 mMatrixFlags &= ~ROTATION_3D;
260 } else {
261 mMatrixFlags |= ROTATION_3D;
262 }
263 }
264 }
265
Romain Guy52036b12013-02-14 18:03:37 -0800266 float getRotationY() const {
267 return mRotationY;
268 }
269
Chris Craik0776a602013-02-14 15:36:01 -0800270 void setScaleX(float scaleX) {
271 if (scaleX != mScaleX) {
272 mScaleX = scaleX;
273 mMatrixDirty = true;
274 if (mScaleX == 1.0f && mScaleY == 1.0f) {
275 mMatrixFlags &= ~SCALE;
276 } else {
277 mMatrixFlags |= SCALE;
278 }
279 }
280 }
281
Romain Guy52036b12013-02-14 18:03:37 -0800282 float getScaleX() const {
283 return mScaleX;
284 }
285
Chris Craik0776a602013-02-14 15:36:01 -0800286 void setScaleY(float scaleY) {
287 if (scaleY != mScaleY) {
288 mScaleY = scaleY;
289 mMatrixDirty = true;
290 if (mScaleX == 1.0f && mScaleY == 1.0f) {
291 mMatrixFlags &= ~SCALE;
292 } else {
293 mMatrixFlags |= SCALE;
294 }
295 }
296 }
297
Romain Guy52036b12013-02-14 18:03:37 -0800298 float getScaleY() const {
299 return mScaleY;
300 }
301
Chris Craik0776a602013-02-14 15:36:01 -0800302 void setPivotX(float pivotX) {
303 mPivotX = pivotX;
304 mMatrixDirty = true;
305 if (mPivotX == 0.0f && mPivotY == 0.0f) {
306 mMatrixFlags &= ~PIVOT;
307 } else {
308 mMatrixFlags |= PIVOT;
309 }
310 mPivotExplicitlySet = true;
311 }
312
Romain Guy52036b12013-02-14 18:03:37 -0800313 ANDROID_API float getPivotX();
314
Chris Craik0776a602013-02-14 15:36:01 -0800315 void setPivotY(float pivotY) {
316 mPivotY = pivotY;
317 mMatrixDirty = true;
318 if (mPivotX == 0.0f && mPivotY == 0.0f) {
319 mMatrixFlags &= ~PIVOT;
320 } else {
321 mMatrixFlags |= PIVOT;
322 }
323 mPivotExplicitlySet = true;
324 }
325
Romain Guy52036b12013-02-14 18:03:37 -0800326 ANDROID_API float getPivotY();
327
Chris Craik0776a602013-02-14 15:36:01 -0800328 void setCameraDistance(float distance) {
329 if (distance != mCameraDistance) {
330 mCameraDistance = distance;
331 mMatrixDirty = true;
332 if (!mTransformCamera) {
333 mTransformCamera = new Sk3DView();
334 mTransformMatrix3D = new SkMatrix();
335 }
336 mTransformCamera->setCameraLocation(0, 0, distance);
337 }
338 }
339
Romain Guy52036b12013-02-14 18:03:37 -0800340 float getCameraDistance() const {
341 return mCameraDistance;
342 }
343
Chris Craik0776a602013-02-14 15:36:01 -0800344 void setLeft(int left) {
345 if (left != mLeft) {
346 mLeft = left;
347 mWidth = mRight - mLeft;
348 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
349 mMatrixDirty = true;
350 }
351 }
352 }
353
Romain Guy52036b12013-02-14 18:03:37 -0800354 float getLeft() const {
355 return mLeft;
356 }
357
Chris Craik0776a602013-02-14 15:36:01 -0800358 void setTop(int top) {
359 if (top != mTop) {
360 mTop = top;
361 mHeight = mBottom - mTop;
362 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
363 mMatrixDirty = true;
364 }
365 }
366 }
367
Romain Guy52036b12013-02-14 18:03:37 -0800368 float getTop() const {
369 return mTop;
370 }
371
Chris Craik0776a602013-02-14 15:36:01 -0800372 void setRight(int right) {
373 if (right != mRight) {
374 mRight = right;
375 mWidth = mRight - mLeft;
376 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
377 mMatrixDirty = true;
378 }
379 }
380 }
381
Romain Guy52036b12013-02-14 18:03:37 -0800382 float getRight() const {
383 return mRight;
384 }
385
Chris Craik0776a602013-02-14 15:36:01 -0800386 void setBottom(int bottom) {
387 if (bottom != mBottom) {
388 mBottom = bottom;
389 mHeight = mBottom - mTop;
390 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
391 mMatrixDirty = true;
392 }
393 }
394 }
395
Romain Guy52036b12013-02-14 18:03:37 -0800396 float getBottom() const {
397 return mBottom;
398 }
399
Chris Craik0776a602013-02-14 15:36:01 -0800400 void setLeftTop(int left, int top) {
401 if (left != mLeft || top != mTop) {
402 mLeft = left;
403 mTop = top;
404 mWidth = mRight - mLeft;
405 mHeight = mBottom - mTop;
406 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
407 mMatrixDirty = true;
408 }
409 }
410 }
411
412 void setLeftTopRightBottom(int left, int top, int right, int bottom) {
413 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
414 mLeft = left;
415 mTop = top;
416 mRight = right;
417 mBottom = bottom;
418 mWidth = mRight - mLeft;
419 mHeight = mBottom - mTop;
420 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
421 mMatrixDirty = true;
422 }
423 }
424 }
425
Romain Guy52036b12013-02-14 18:03:37 -0800426 void offsetLeftRight(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800427 if (offset != 0) {
428 mLeft += offset;
429 mRight += offset;
430 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
431 mMatrixDirty = true;
432 }
433 }
434 }
435
Romain Guy52036b12013-02-14 18:03:37 -0800436 void offsetTopBottom(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800437 if (offset != 0) {
438 mTop += offset;
439 mBottom += offset;
440 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
441 mMatrixDirty = true;
442 }
443 }
444 }
445
446 void setCaching(bool caching) {
447 mCaching = caching;
448 }
449
450 int getWidth() {
451 return mWidth;
452 }
453
454 int getHeight() {
455 return mHeight;
456 }
457
458private:
Chris Craikff785832013-03-08 13:12:16 -0800459 void outputViewProperties(const int level);
460
461 template <class T>
462 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
463
464 template <class T>
465 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
466
Chris Craik0776a602013-02-14 15:36:01 -0800467 void init();
468
469 void clearResources();
470
471 void updateMatrix();
472
473 class TextContainer {
474 public:
475 size_t length() const {
476 return mByteLength;
477 }
478
479 const char* text() const {
480 return (const char*) mText;
481 }
482
483 size_t mByteLength;
484 const char* mText;
485 };
486
487 Vector<SkBitmap*> mBitmapResources;
488 Vector<SkBitmap*> mOwnedBitmapResources;
489 Vector<SkiaColorFilter*> mFilterResources;
Romain Guye3b0a012013-06-26 15:45:41 -0700490 Vector<Res_png_9patch*> mPatchResources;
Chris Craik0776a602013-02-14 15:36:01 -0800491
492 Vector<SkPaint*> mPaints;
493 Vector<SkPath*> mPaths;
494 SortedVector<SkPath*> mSourcePaths;
495 Vector<SkRegion*> mRegions;
496 Vector<SkMatrix*> mMatrices;
497 Vector<SkiaShader*> mShaders;
498 Vector<Layer*> mLayers;
499
500 sp<DisplayListData> mDisplayListData;
501
502 size_t mSize;
503
504 bool mIsRenderable;
505 uint32_t mFunctorCount;
506
507 String8 mName;
Chris Craik9846de62013-06-12 16:23:00 -0700508 bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
Chris Craik0776a602013-02-14 15:36:01 -0800509
510 // View properties
Chet Haasedd671592013-04-19 14:54:34 -0700511 bool mClipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800512 float mAlpha;
Chris Craik0776a602013-02-14 15:36:01 -0800513 bool mHasOverlappingRendering;
514 float mTranslationX, mTranslationY;
515 float mRotation, mRotationX, mRotationY;
516 float mScaleX, mScaleY;
517 float mPivotX, mPivotY;
518 float mCameraDistance;
519 int mLeft, mTop, mRight, mBottom;
520 int mWidth, mHeight;
521 int mPrevWidth, mPrevHeight;
522 bool mPivotExplicitlySet;
523 bool mMatrixDirty;
524 bool mMatrixIsIdentity;
525 uint32_t mMatrixFlags;
526 SkMatrix* mTransformMatrix;
527 Sk3DView* mTransformCamera;
528 SkMatrix* mTransformMatrix3D;
529 SkMatrix* mStaticMatrix;
530 SkMatrix* mAnimationMatrix;
531 bool mCaching;
Chris Craikff785832013-03-08 13:12:16 -0800532
533 /**
534 * State operations - needed to defer displayList property operations (for example, when setting
535 * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
536 * allocation, or null if uninitialized.
537 *
Chris Craik9846de62013-06-12 16:23:00 -0700538 * These are initialized (via friend re-constructors) when a displayList is issued in either
539 * replay or deferred mode. If replaying, the ops are not used until the next frame. If
540 * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time.
Chris Craikff785832013-03-08 13:12:16 -0800541 *
Chris Craik9846de62013-06-12 16:23:00 -0700542 * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data
Chris Craikff785832013-03-08 13:12:16 -0800543 */
544 ClipRectOp* mClipRectOp;
545 SaveLayerOp* mSaveLayerOp;
546 SaveOp* mSaveOp;
547 RestoreToCountOp* mRestoreToCountOp;
Chris Craik0776a602013-02-14 15:36:01 -0800548}; // class DisplayList
549
550}; // namespace uirenderer
551}; // namespace android
552
553#endif // ANDROID_HWUI_OPENGL_RENDERER_H