blob: 5f843291f847997ed8e3a786dd70eb45efc16d22 [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>
33#include <cutils/compiler.h>
34
35#include "utils/LinearAllocator.h"
36
37#include "Debug.h"
38
39#define TRANSLATION 0x0001
40#define ROTATION 0x0002
41#define ROTATION_3D 0x0004
42#define SCALE 0x0008
43#define PIVOT 0x0010
44
45class SkBitmap;
46class SkPaint;
47class SkPath;
48class SkRegion;
49
50namespace android {
51namespace uirenderer {
52
Chris Craikc3566d02013-02-04 16:16:33 -080053class DeferredDisplayList;
Chris Craik0776a602013-02-14 15:36:01 -080054class DisplayListOp;
55class DisplayListRenderer;
56class OpenGLRenderer;
57class Rect;
58class Layer;
59class SkiaColorFilter;
60class SkiaShader;
61
Chris Craikff785832013-03-08 13:12:16 -080062class ClipRectOp;
63class SaveLayerOp;
64class SaveOp;
65class RestoreToCountOp;
66
67struct DeferStateStruct {
68 DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
69 : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {}
70 DeferredDisplayList& mDeferredList;
71 OpenGLRenderer& mRenderer;
72 const int mReplayFlags;
73};
74
75struct ReplayStateStruct {
76 ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
77 : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags),
78 mDrawGlStatus(DrawGlInfo::kStatusDone) {}
79 OpenGLRenderer& mRenderer;
80 Rect& mDirty;
81 const int mReplayFlags;
82 status_t mDrawGlStatus;
83};
84
Chris Craik0776a602013-02-14 15:36:01 -080085/**
86 * Refcounted structure that holds data used in display list stream
87 */
Chris Craikff785832013-03-08 13:12:16 -080088class DisplayListData : public LightRefBase<DisplayListData> {
Chris Craik0776a602013-02-14 15:36:01 -080089public:
90 LinearAllocator allocator;
91 Vector<DisplayListOp*> displayListOps;
92};
93
94/**
95 * Replays recorded drawing commands.
96 */
97class DisplayList {
98public:
99 DisplayList(const DisplayListRenderer& recorder);
100 ANDROID_API ~DisplayList();
101
102 // See flags defined in DisplayList.java
103 enum ReplayFlag {
104 kReplayFlag_ClipChildren = 0x1
105 };
106
Chris Craik0776a602013-02-14 15:36:01 -0800107
108 ANDROID_API size_t getSize();
109 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
110 ANDROID_API static void outputLogBuffer(int fd);
111
112 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
113
Chris Craikff785832013-03-08 13:12:16 -0800114
115 void defer(DeferStateStruct& deferStruct, const int level);
116 void replay(ReplayStateStruct& replayStruct, const int level);
Chris Craik0776a602013-02-14 15:36:01 -0800117
118 void output(uint32_t level = 0);
119
120 ANDROID_API void reset();
121
122 void setRenderable(bool renderable) {
123 mIsRenderable = renderable;
124 }
125
126 bool isRenderable() const {
127 return mIsRenderable;
128 }
129
130 void setName(const char* name) {
131 if (name) {
132 mName.setTo(name);
133 }
134 }
135
Romain Guy52036b12013-02-14 18:03:37 -0800136 const char* getName() const {
137 return mName.string();
138 }
139
Chet Haasedd671592013-04-19 14:54:34 -0700140 void setClipToBounds(bool clipToBounds) {
141 mClipToBounds = clipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800142 }
143
144 void setStaticMatrix(SkMatrix* matrix) {
145 delete mStaticMatrix;
146 mStaticMatrix = new SkMatrix(*matrix);
147 }
148
Romain Guy52036b12013-02-14 18:03:37 -0800149 // Can return NULL
150 SkMatrix* getStaticMatrix() {
151 return mStaticMatrix;
152 }
153
Chris Craik0776a602013-02-14 15:36:01 -0800154 void setAnimationMatrix(SkMatrix* matrix) {
155 delete mAnimationMatrix;
156 if (matrix) {
157 mAnimationMatrix = new SkMatrix(*matrix);
158 } else {
159 mAnimationMatrix = NULL;
160 }
161 }
162
163 void setAlpha(float alpha) {
164 alpha = fminf(1.0f, fmaxf(0.0f, alpha));
165 if (alpha != mAlpha) {
166 mAlpha = alpha;
Chris Craik0776a602013-02-14 15:36:01 -0800167 }
168 }
169
Romain Guy52036b12013-02-14 18:03:37 -0800170 float getAlpha() const {
171 return mAlpha;
172 }
173
Chris Craik0776a602013-02-14 15:36:01 -0800174 void setHasOverlappingRendering(bool hasOverlappingRendering) {
175 mHasOverlappingRendering = hasOverlappingRendering;
176 }
177
Romain Guy52036b12013-02-14 18:03:37 -0800178 bool hasOverlappingRendering() const {
179 return mHasOverlappingRendering;
180 }
181
Chris Craik0776a602013-02-14 15:36:01 -0800182 void setTranslationX(float translationX) {
183 if (translationX != mTranslationX) {
184 mTranslationX = translationX;
185 mMatrixDirty = true;
186 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
187 mMatrixFlags &= ~TRANSLATION;
188 } else {
189 mMatrixFlags |= TRANSLATION;
190 }
191 }
192 }
193
Romain Guy52036b12013-02-14 18:03:37 -0800194 float getTranslationX() const {
195 return mTranslationX;
196 }
197
Chris Craik0776a602013-02-14 15:36:01 -0800198 void setTranslationY(float translationY) {
199 if (translationY != mTranslationY) {
200 mTranslationY = translationY;
201 mMatrixDirty = true;
202 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
203 mMatrixFlags &= ~TRANSLATION;
204 } else {
205 mMatrixFlags |= TRANSLATION;
206 }
207 }
208 }
209
Romain Guy52036b12013-02-14 18:03:37 -0800210 float getTranslationY() const {
211 return mTranslationY;
212 }
213
Chris Craik0776a602013-02-14 15:36:01 -0800214 void setRotation(float rotation) {
215 if (rotation != mRotation) {
216 mRotation = rotation;
217 mMatrixDirty = true;
218 if (mRotation == 0.0f) {
219 mMatrixFlags &= ~ROTATION;
220 } else {
221 mMatrixFlags |= ROTATION;
222 }
223 }
224 }
225
Romain Guy52036b12013-02-14 18:03:37 -0800226 float getRotation() const {
227 return mRotation;
228 }
229
Chris Craik0776a602013-02-14 15:36:01 -0800230 void setRotationX(float rotationX) {
231 if (rotationX != mRotationX) {
232 mRotationX = rotationX;
233 mMatrixDirty = true;
234 if (mRotationX == 0.0f && mRotationY == 0.0f) {
235 mMatrixFlags &= ~ROTATION_3D;
236 } else {
237 mMatrixFlags |= ROTATION_3D;
238 }
239 }
240 }
241
Romain Guy52036b12013-02-14 18:03:37 -0800242 float getRotationX() const {
243 return mRotationX;
244 }
245
Chris Craik0776a602013-02-14 15:36:01 -0800246 void setRotationY(float rotationY) {
247 if (rotationY != mRotationY) {
248 mRotationY = rotationY;
249 mMatrixDirty = true;
250 if (mRotationX == 0.0f && mRotationY == 0.0f) {
251 mMatrixFlags &= ~ROTATION_3D;
252 } else {
253 mMatrixFlags |= ROTATION_3D;
254 }
255 }
256 }
257
Romain Guy52036b12013-02-14 18:03:37 -0800258 float getRotationY() const {
259 return mRotationY;
260 }
261
Chris Craik0776a602013-02-14 15:36:01 -0800262 void setScaleX(float scaleX) {
263 if (scaleX != mScaleX) {
264 mScaleX = scaleX;
265 mMatrixDirty = true;
266 if (mScaleX == 1.0f && mScaleY == 1.0f) {
267 mMatrixFlags &= ~SCALE;
268 } else {
269 mMatrixFlags |= SCALE;
270 }
271 }
272 }
273
Romain Guy52036b12013-02-14 18:03:37 -0800274 float getScaleX() const {
275 return mScaleX;
276 }
277
Chris Craik0776a602013-02-14 15:36:01 -0800278 void setScaleY(float scaleY) {
279 if (scaleY != mScaleY) {
280 mScaleY = scaleY;
281 mMatrixDirty = true;
282 if (mScaleX == 1.0f && mScaleY == 1.0f) {
283 mMatrixFlags &= ~SCALE;
284 } else {
285 mMatrixFlags |= SCALE;
286 }
287 }
288 }
289
Romain Guy52036b12013-02-14 18:03:37 -0800290 float getScaleY() const {
291 return mScaleY;
292 }
293
Chris Craik0776a602013-02-14 15:36:01 -0800294 void setPivotX(float pivotX) {
295 mPivotX = pivotX;
296 mMatrixDirty = true;
297 if (mPivotX == 0.0f && mPivotY == 0.0f) {
298 mMatrixFlags &= ~PIVOT;
299 } else {
300 mMatrixFlags |= PIVOT;
301 }
302 mPivotExplicitlySet = true;
303 }
304
Romain Guy52036b12013-02-14 18:03:37 -0800305 ANDROID_API float getPivotX();
306
Chris Craik0776a602013-02-14 15:36:01 -0800307 void setPivotY(float pivotY) {
308 mPivotY = pivotY;
309 mMatrixDirty = true;
310 if (mPivotX == 0.0f && mPivotY == 0.0f) {
311 mMatrixFlags &= ~PIVOT;
312 } else {
313 mMatrixFlags |= PIVOT;
314 }
315 mPivotExplicitlySet = true;
316 }
317
Romain Guy52036b12013-02-14 18:03:37 -0800318 ANDROID_API float getPivotY();
319
Chris Craik0776a602013-02-14 15:36:01 -0800320 void setCameraDistance(float distance) {
321 if (distance != mCameraDistance) {
322 mCameraDistance = distance;
323 mMatrixDirty = true;
324 if (!mTransformCamera) {
325 mTransformCamera = new Sk3DView();
326 mTransformMatrix3D = new SkMatrix();
327 }
328 mTransformCamera->setCameraLocation(0, 0, distance);
329 }
330 }
331
Romain Guy52036b12013-02-14 18:03:37 -0800332 float getCameraDistance() const {
333 return mCameraDistance;
334 }
335
Chris Craik0776a602013-02-14 15:36:01 -0800336 void setLeft(int left) {
337 if (left != mLeft) {
338 mLeft = left;
339 mWidth = mRight - mLeft;
340 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
341 mMatrixDirty = true;
342 }
343 }
344 }
345
Romain Guy52036b12013-02-14 18:03:37 -0800346 float getLeft() const {
347 return mLeft;
348 }
349
Chris Craik0776a602013-02-14 15:36:01 -0800350 void setTop(int top) {
351 if (top != mTop) {
352 mTop = top;
353 mHeight = mBottom - mTop;
354 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
355 mMatrixDirty = true;
356 }
357 }
358 }
359
Romain Guy52036b12013-02-14 18:03:37 -0800360 float getTop() const {
361 return mTop;
362 }
363
Chris Craik0776a602013-02-14 15:36:01 -0800364 void setRight(int right) {
365 if (right != mRight) {
366 mRight = right;
367 mWidth = mRight - mLeft;
368 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
369 mMatrixDirty = true;
370 }
371 }
372 }
373
Romain Guy52036b12013-02-14 18:03:37 -0800374 float getRight() const {
375 return mRight;
376 }
377
Chris Craik0776a602013-02-14 15:36:01 -0800378 void setBottom(int bottom) {
379 if (bottom != mBottom) {
380 mBottom = bottom;
381 mHeight = mBottom - mTop;
382 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
383 mMatrixDirty = true;
384 }
385 }
386 }
387
Romain Guy52036b12013-02-14 18:03:37 -0800388 float getBottom() const {
389 return mBottom;
390 }
391
Chris Craik0776a602013-02-14 15:36:01 -0800392 void setLeftTop(int left, int top) {
393 if (left != mLeft || top != mTop) {
394 mLeft = left;
395 mTop = top;
396 mWidth = mRight - mLeft;
397 mHeight = mBottom - mTop;
398 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
399 mMatrixDirty = true;
400 }
401 }
402 }
403
404 void setLeftTopRightBottom(int left, int top, int right, int bottom) {
405 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
406 mLeft = left;
407 mTop = top;
408 mRight = right;
409 mBottom = bottom;
410 mWidth = mRight - mLeft;
411 mHeight = mBottom - mTop;
412 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
413 mMatrixDirty = true;
414 }
415 }
416 }
417
Romain Guy52036b12013-02-14 18:03:37 -0800418 void offsetLeftRight(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800419 if (offset != 0) {
420 mLeft += offset;
421 mRight += offset;
422 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
423 mMatrixDirty = true;
424 }
425 }
426 }
427
Romain Guy52036b12013-02-14 18:03:37 -0800428 void offsetTopBottom(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800429 if (offset != 0) {
430 mTop += offset;
431 mBottom += offset;
432 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
433 mMatrixDirty = true;
434 }
435 }
436 }
437
438 void setCaching(bool caching) {
439 mCaching = caching;
440 }
441
442 int getWidth() {
443 return mWidth;
444 }
445
446 int getHeight() {
447 return mHeight;
448 }
449
450private:
Chris Craikff785832013-03-08 13:12:16 -0800451 void outputViewProperties(const int level);
452
453 template <class T>
454 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
455
456 template <class T>
457 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
458
Chris Craik0776a602013-02-14 15:36:01 -0800459 void init();
460
461 void clearResources();
462
463 void updateMatrix();
464
465 class TextContainer {
466 public:
467 size_t length() const {
468 return mByteLength;
469 }
470
471 const char* text() const {
472 return (const char*) mText;
473 }
474
475 size_t mByteLength;
476 const char* mText;
477 };
478
479 Vector<SkBitmap*> mBitmapResources;
480 Vector<SkBitmap*> mOwnedBitmapResources;
481 Vector<SkiaColorFilter*> mFilterResources;
482
483 Vector<SkPaint*> mPaints;
484 Vector<SkPath*> mPaths;
485 SortedVector<SkPath*> mSourcePaths;
486 Vector<SkRegion*> mRegions;
487 Vector<SkMatrix*> mMatrices;
488 Vector<SkiaShader*> mShaders;
489 Vector<Layer*> mLayers;
490
491 sp<DisplayListData> mDisplayListData;
492
493 size_t mSize;
494
495 bool mIsRenderable;
496 uint32_t mFunctorCount;
497
498 String8 mName;
499
500 // View properties
Chet Haasedd671592013-04-19 14:54:34 -0700501 bool mClipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800502 float mAlpha;
Chris Craik0776a602013-02-14 15:36:01 -0800503 bool mHasOverlappingRendering;
504 float mTranslationX, mTranslationY;
505 float mRotation, mRotationX, mRotationY;
506 float mScaleX, mScaleY;
507 float mPivotX, mPivotY;
508 float mCameraDistance;
509 int mLeft, mTop, mRight, mBottom;
510 int mWidth, mHeight;
511 int mPrevWidth, mPrevHeight;
512 bool mPivotExplicitlySet;
513 bool mMatrixDirty;
514 bool mMatrixIsIdentity;
515 uint32_t mMatrixFlags;
516 SkMatrix* mTransformMatrix;
517 Sk3DView* mTransformCamera;
518 SkMatrix* mTransformMatrix3D;
519 SkMatrix* mStaticMatrix;
520 SkMatrix* mAnimationMatrix;
521 bool mCaching;
Chris Craikff785832013-03-08 13:12:16 -0800522
523 /**
524 * State operations - needed to defer displayList property operations (for example, when setting
525 * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
526 * allocation, or null if uninitialized.
527 *
528 * These are initialized (via friend constructors) when a displayList is issued in either replay
529 * or deferred mode. If replaying, the ops are not used until the next frame. If deferring, the
530 * ops may be stored in the DeferredDisplayList to be played back a second time.
531 *
532 * They should be used at most once per frame (one call to iterate)
533 */
534 ClipRectOp* mClipRectOp;
535 SaveLayerOp* mSaveLayerOp;
536 SaveOp* mSaveOp;
537 RestoreToCountOp* mRestoreToCountOp;
Chris Craik0776a602013-02-14 15:36:01 -0800538}; // class DisplayList
539
540}; // namespace uirenderer
541}; // namespace android
542
543#endif // ANDROID_HWUI_OPENGL_RENDERER_H