blob: 1cd5f1c4d967401a54aa79b6c2addd7cdc0aebf3 [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 Craikc1c5f082013-09-11 16:23:37 -070029#include <utils/LinearAllocator.h>
Chris Craik0776a602013-02-14 15:36:01 -080030#include <utils/RefBase.h>
31#include <utils/SortedVector.h>
32#include <utils/String8.h>
33#include <utils/Vector.h>
Romain Guye3b0a012013-06-26 15:45:41 -070034
Chris Craik0776a602013-02-14 15:36:01 -080035#include <cutils/compiler.h>
36
Romain Guye3b0a012013-06-26 15:45:41 -070037#include <androidfw/ResourceTypes.h>
38
Chris Craik0776a602013-02-14 15:36:01 -080039#include "Debug.h"
40
41#define TRANSLATION 0x0001
42#define ROTATION 0x0002
43#define ROTATION_3D 0x0004
44#define SCALE 0x0008
45#define PIVOT 0x0010
46
47class SkBitmap;
48class SkPaint;
49class SkPath;
50class SkRegion;
51
52namespace android {
53namespace uirenderer {
54
Chris Craikc3566d02013-02-04 16:16:33 -080055class DeferredDisplayList;
Chris Craik0776a602013-02-14 15:36:01 -080056class DisplayListOp;
57class DisplayListRenderer;
58class OpenGLRenderer;
59class Rect;
60class Layer;
61class SkiaColorFilter;
62class SkiaShader;
63
Chris Craikff785832013-03-08 13:12:16 -080064class ClipRectOp;
65class SaveLayerOp;
66class SaveOp;
67class RestoreToCountOp;
68
69struct DeferStateStruct {
70 DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
71 : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {}
72 DeferredDisplayList& mDeferredList;
73 OpenGLRenderer& mRenderer;
74 const int mReplayFlags;
75};
76
77struct ReplayStateStruct {
78 ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
79 : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags),
80 mDrawGlStatus(DrawGlInfo::kStatusDone) {}
81 OpenGLRenderer& mRenderer;
82 Rect& mDirty;
83 const int mReplayFlags;
84 status_t mDrawGlStatus;
85};
86
Chris Craik0776a602013-02-14 15:36:01 -080087/**
88 * Refcounted structure that holds data used in display list stream
89 */
Chris Craikff785832013-03-08 13:12:16 -080090class DisplayListData : public LightRefBase<DisplayListData> {
Chris Craik0776a602013-02-14 15:36:01 -080091public:
92 LinearAllocator allocator;
93 Vector<DisplayListOp*> displayListOps;
94};
95
96/**
97 * Replays recorded drawing commands.
98 */
99class DisplayList {
100public:
101 DisplayList(const DisplayListRenderer& recorder);
102 ANDROID_API ~DisplayList();
103
104 // See flags defined in DisplayList.java
105 enum ReplayFlag {
106 kReplayFlag_ClipChildren = 0x1
107 };
108
Chris Craik0776a602013-02-14 15:36:01 -0800109
110 ANDROID_API size_t getSize();
111 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
112 ANDROID_API static void outputLogBuffer(int fd);
113
114 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
115
Chris Craikff785832013-03-08 13:12:16 -0800116 void defer(DeferStateStruct& deferStruct, const int level);
117 void replay(ReplayStateStruct& replayStruct, const int level);
Chris Craik0776a602013-02-14 15:36:01 -0800118
119 void output(uint32_t level = 0);
120
121 ANDROID_API void reset();
122
123 void setRenderable(bool renderable) {
124 mIsRenderable = renderable;
125 }
126
127 bool isRenderable() const {
128 return mIsRenderable;
129 }
130
131 void setName(const char* name) {
132 if (name) {
Romain Guy450dc752013-06-05 14:14:03 -0700133 char* lastPeriod = strrchr(name, '.');
134 if (lastPeriod) {
135 mName.setTo(lastPeriod + 1);
136 } else {
137 mName.setTo(name);
138 }
Chris Craik0776a602013-02-14 15:36:01 -0800139 }
140 }
141
Romain Guy52036b12013-02-14 18:03:37 -0800142 const char* getName() const {
143 return mName.string();
144 }
145
Chet Haasedd671592013-04-19 14:54:34 -0700146 void setClipToBounds(bool clipToBounds) {
147 mClipToBounds = clipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800148 }
149
150 void setStaticMatrix(SkMatrix* matrix) {
151 delete mStaticMatrix;
152 mStaticMatrix = new SkMatrix(*matrix);
153 }
154
Romain Guy52036b12013-02-14 18:03:37 -0800155 // Can return NULL
156 SkMatrix* getStaticMatrix() {
157 return mStaticMatrix;
158 }
159
Chris Craik0776a602013-02-14 15:36:01 -0800160 void setAnimationMatrix(SkMatrix* matrix) {
161 delete mAnimationMatrix;
162 if (matrix) {
163 mAnimationMatrix = new SkMatrix(*matrix);
164 } else {
165 mAnimationMatrix = NULL;
166 }
167 }
168
169 void setAlpha(float alpha) {
170 alpha = fminf(1.0f, fmaxf(0.0f, alpha));
171 if (alpha != mAlpha) {
172 mAlpha = alpha;
Chris Craik0776a602013-02-14 15:36:01 -0800173 }
174 }
175
Romain Guy52036b12013-02-14 18:03:37 -0800176 float getAlpha() const {
177 return mAlpha;
178 }
179
Chris Craik0776a602013-02-14 15:36:01 -0800180 void setHasOverlappingRendering(bool hasOverlappingRendering) {
181 mHasOverlappingRendering = hasOverlappingRendering;
182 }
183
Romain Guy52036b12013-02-14 18:03:37 -0800184 bool hasOverlappingRendering() const {
185 return mHasOverlappingRendering;
186 }
187
Chris Craik0776a602013-02-14 15:36:01 -0800188 void setTranslationX(float translationX) {
189 if (translationX != mTranslationX) {
190 mTranslationX = translationX;
191 mMatrixDirty = true;
192 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
193 mMatrixFlags &= ~TRANSLATION;
194 } else {
195 mMatrixFlags |= TRANSLATION;
196 }
197 }
198 }
199
Romain Guy52036b12013-02-14 18:03:37 -0800200 float getTranslationX() const {
201 return mTranslationX;
202 }
203
Chris Craik0776a602013-02-14 15:36:01 -0800204 void setTranslationY(float translationY) {
205 if (translationY != mTranslationY) {
206 mTranslationY = translationY;
207 mMatrixDirty = true;
208 if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
209 mMatrixFlags &= ~TRANSLATION;
210 } else {
211 mMatrixFlags |= TRANSLATION;
212 }
213 }
214 }
215
Romain Guy52036b12013-02-14 18:03:37 -0800216 float getTranslationY() const {
217 return mTranslationY;
218 }
219
Chris Craik0776a602013-02-14 15:36:01 -0800220 void setRotation(float rotation) {
221 if (rotation != mRotation) {
222 mRotation = rotation;
223 mMatrixDirty = true;
224 if (mRotation == 0.0f) {
225 mMatrixFlags &= ~ROTATION;
226 } else {
227 mMatrixFlags |= ROTATION;
228 }
229 }
230 }
231
Romain Guy52036b12013-02-14 18:03:37 -0800232 float getRotation() const {
233 return mRotation;
234 }
235
Chris Craik0776a602013-02-14 15:36:01 -0800236 void setRotationX(float rotationX) {
237 if (rotationX != mRotationX) {
238 mRotationX = rotationX;
239 mMatrixDirty = true;
240 if (mRotationX == 0.0f && mRotationY == 0.0f) {
241 mMatrixFlags &= ~ROTATION_3D;
242 } else {
243 mMatrixFlags |= ROTATION_3D;
244 }
245 }
246 }
247
Romain Guy52036b12013-02-14 18:03:37 -0800248 float getRotationX() const {
249 return mRotationX;
250 }
251
Chris Craik0776a602013-02-14 15:36:01 -0800252 void setRotationY(float rotationY) {
253 if (rotationY != mRotationY) {
254 mRotationY = rotationY;
255 mMatrixDirty = true;
256 if (mRotationX == 0.0f && mRotationY == 0.0f) {
257 mMatrixFlags &= ~ROTATION_3D;
258 } else {
259 mMatrixFlags |= ROTATION_3D;
260 }
261 }
262 }
263
Romain Guy52036b12013-02-14 18:03:37 -0800264 float getRotationY() const {
265 return mRotationY;
266 }
267
Chris Craik0776a602013-02-14 15:36:01 -0800268 void setScaleX(float scaleX) {
269 if (scaleX != mScaleX) {
270 mScaleX = scaleX;
271 mMatrixDirty = true;
272 if (mScaleX == 1.0f && mScaleY == 1.0f) {
273 mMatrixFlags &= ~SCALE;
274 } else {
275 mMatrixFlags |= SCALE;
276 }
277 }
278 }
279
Romain Guy52036b12013-02-14 18:03:37 -0800280 float getScaleX() const {
281 return mScaleX;
282 }
283
Chris Craik0776a602013-02-14 15:36:01 -0800284 void setScaleY(float scaleY) {
285 if (scaleY != mScaleY) {
286 mScaleY = scaleY;
287 mMatrixDirty = true;
288 if (mScaleX == 1.0f && mScaleY == 1.0f) {
289 mMatrixFlags &= ~SCALE;
290 } else {
291 mMatrixFlags |= SCALE;
292 }
293 }
294 }
295
Romain Guy52036b12013-02-14 18:03:37 -0800296 float getScaleY() const {
297 return mScaleY;
298 }
299
Chris Craik0776a602013-02-14 15:36:01 -0800300 void setPivotX(float pivotX) {
301 mPivotX = pivotX;
302 mMatrixDirty = true;
303 if (mPivotX == 0.0f && mPivotY == 0.0f) {
304 mMatrixFlags &= ~PIVOT;
305 } else {
306 mMatrixFlags |= PIVOT;
307 }
308 mPivotExplicitlySet = true;
309 }
310
Romain Guy52036b12013-02-14 18:03:37 -0800311 ANDROID_API float getPivotX();
312
Chris Craik0776a602013-02-14 15:36:01 -0800313 void setPivotY(float pivotY) {
314 mPivotY = pivotY;
315 mMatrixDirty = true;
316 if (mPivotX == 0.0f && mPivotY == 0.0f) {
317 mMatrixFlags &= ~PIVOT;
318 } else {
319 mMatrixFlags |= PIVOT;
320 }
321 mPivotExplicitlySet = true;
322 }
323
Romain Guy52036b12013-02-14 18:03:37 -0800324 ANDROID_API float getPivotY();
325
Chris Craik0776a602013-02-14 15:36:01 -0800326 void setCameraDistance(float distance) {
327 if (distance != mCameraDistance) {
328 mCameraDistance = distance;
329 mMatrixDirty = true;
330 if (!mTransformCamera) {
331 mTransformCamera = new Sk3DView();
332 mTransformMatrix3D = new SkMatrix();
333 }
334 mTransformCamera->setCameraLocation(0, 0, distance);
335 }
336 }
337
Romain Guy52036b12013-02-14 18:03:37 -0800338 float getCameraDistance() const {
339 return mCameraDistance;
340 }
341
Chris Craik0776a602013-02-14 15:36:01 -0800342 void setLeft(int left) {
343 if (left != mLeft) {
344 mLeft = left;
345 mWidth = mRight - mLeft;
346 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
347 mMatrixDirty = true;
348 }
349 }
350 }
351
Romain Guy52036b12013-02-14 18:03:37 -0800352 float getLeft() const {
353 return mLeft;
354 }
355
Chris Craik0776a602013-02-14 15:36:01 -0800356 void setTop(int top) {
357 if (top != mTop) {
358 mTop = top;
359 mHeight = mBottom - mTop;
360 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
361 mMatrixDirty = true;
362 }
363 }
364 }
365
Romain Guy52036b12013-02-14 18:03:37 -0800366 float getTop() const {
367 return mTop;
368 }
369
Chris Craik0776a602013-02-14 15:36:01 -0800370 void setRight(int right) {
371 if (right != mRight) {
372 mRight = right;
373 mWidth = mRight - mLeft;
374 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
375 mMatrixDirty = true;
376 }
377 }
378 }
379
Romain Guy52036b12013-02-14 18:03:37 -0800380 float getRight() const {
381 return mRight;
382 }
383
Chris Craik0776a602013-02-14 15:36:01 -0800384 void setBottom(int bottom) {
385 if (bottom != mBottom) {
386 mBottom = bottom;
387 mHeight = mBottom - mTop;
388 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
389 mMatrixDirty = true;
390 }
391 }
392 }
393
Romain Guy52036b12013-02-14 18:03:37 -0800394 float getBottom() const {
395 return mBottom;
396 }
397
Chris Craik0776a602013-02-14 15:36:01 -0800398 void setLeftTop(int left, int top) {
399 if (left != mLeft || top != mTop) {
400 mLeft = left;
401 mTop = top;
402 mWidth = mRight - mLeft;
403 mHeight = mBottom - mTop;
404 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
405 mMatrixDirty = true;
406 }
407 }
408 }
409
410 void setLeftTopRightBottom(int left, int top, int right, int bottom) {
411 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
412 mLeft = left;
413 mTop = top;
414 mRight = right;
415 mBottom = bottom;
416 mWidth = mRight - mLeft;
417 mHeight = mBottom - mTop;
418 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
419 mMatrixDirty = true;
420 }
421 }
422 }
423
Romain Guy52036b12013-02-14 18:03:37 -0800424 void offsetLeftRight(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800425 if (offset != 0) {
426 mLeft += offset;
427 mRight += offset;
428 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
429 mMatrixDirty = true;
430 }
431 }
432 }
433
Romain Guy52036b12013-02-14 18:03:37 -0800434 void offsetTopBottom(float offset) {
Chris Craik0776a602013-02-14 15:36:01 -0800435 if (offset != 0) {
436 mTop += offset;
437 mBottom += offset;
438 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
439 mMatrixDirty = true;
440 }
441 }
442 }
443
444 void setCaching(bool caching) {
445 mCaching = caching;
446 }
447
448 int getWidth() {
449 return mWidth;
450 }
451
452 int getHeight() {
453 return mHeight;
454 }
455
456private:
Chris Craikff785832013-03-08 13:12:16 -0800457 void outputViewProperties(const int level);
458
459 template <class T>
460 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
461
462 template <class T>
463 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
464
Chris Craik0776a602013-02-14 15:36:01 -0800465 void init();
466
467 void clearResources();
468
469 void updateMatrix();
470
471 class TextContainer {
472 public:
473 size_t length() const {
474 return mByteLength;
475 }
476
477 const char* text() const {
478 return (const char*) mText;
479 }
480
481 size_t mByteLength;
482 const char* mText;
483 };
484
485 Vector<SkBitmap*> mBitmapResources;
486 Vector<SkBitmap*> mOwnedBitmapResources;
487 Vector<SkiaColorFilter*> mFilterResources;
Romain Guye3b0a012013-06-26 15:45:41 -0700488 Vector<Res_png_9patch*> mPatchResources;
Chris Craik0776a602013-02-14 15:36:01 -0800489
490 Vector<SkPaint*> mPaints;
491 Vector<SkPath*> mPaths;
492 SortedVector<SkPath*> mSourcePaths;
493 Vector<SkRegion*> mRegions;
494 Vector<SkMatrix*> mMatrices;
495 Vector<SkiaShader*> mShaders;
496 Vector<Layer*> mLayers;
497
498 sp<DisplayListData> mDisplayListData;
499
500 size_t mSize;
501
502 bool mIsRenderable;
503 uint32_t mFunctorCount;
504
505 String8 mName;
Chris Craik9846de62013-06-12 16:23:00 -0700506 bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
Chris Craik0776a602013-02-14 15:36:01 -0800507
508 // View properties
Chet Haasedd671592013-04-19 14:54:34 -0700509 bool mClipToBounds;
Chris Craik0776a602013-02-14 15:36:01 -0800510 float mAlpha;
Chris Craik0776a602013-02-14 15:36:01 -0800511 bool mHasOverlappingRendering;
512 float mTranslationX, mTranslationY;
513 float mRotation, mRotationX, mRotationY;
514 float mScaleX, mScaleY;
515 float mPivotX, mPivotY;
516 float mCameraDistance;
517 int mLeft, mTop, mRight, mBottom;
518 int mWidth, mHeight;
519 int mPrevWidth, mPrevHeight;
520 bool mPivotExplicitlySet;
521 bool mMatrixDirty;
522 bool mMatrixIsIdentity;
523 uint32_t mMatrixFlags;
524 SkMatrix* mTransformMatrix;
525 Sk3DView* mTransformCamera;
526 SkMatrix* mTransformMatrix3D;
527 SkMatrix* mStaticMatrix;
528 SkMatrix* mAnimationMatrix;
529 bool mCaching;
Chris Craikff785832013-03-08 13:12:16 -0800530
531 /**
532 * State operations - needed to defer displayList property operations (for example, when setting
533 * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
534 * allocation, or null if uninitialized.
535 *
Chris Craik9846de62013-06-12 16:23:00 -0700536 * These are initialized (via friend re-constructors) when a displayList is issued in either
537 * replay or deferred mode. If replaying, the ops are not used until the next frame. If
538 * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time.
Chris Craikff785832013-03-08 13:12:16 -0800539 *
Chris Craik9846de62013-06-12 16:23:00 -0700540 * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data
Chris Craikff785832013-03-08 13:12:16 -0800541 */
542 ClipRectOp* mClipRectOp;
543 SaveLayerOp* mSaveLayerOp;
544 SaveOp* mSaveOp;
545 RestoreToCountOp* mRestoreToCountOp;
Chris Craik0776a602013-02-14 15:36:01 -0800546}; // class DisplayList
547
548}; // namespace uirenderer
549}; // namespace android
550
551#endif // ANDROID_HWUI_OPENGL_RENDERER_H