CanvasState.h revision e84a208317e0ed388fcdad1e6743c7849acb51b0
1/* 2 * Copyright (C) 2014 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_CANVAS_STATE_H 18#define ANDROID_HWUI_CANVAS_STATE_H 19 20#include <SkMatrix.h> 21#include <SkPath.h> 22#include <SkRegion.h> 23 24#include "Snapshot.h" 25 26namespace android { 27namespace uirenderer { 28 29/** 30 * Abstract base class for any class containing CanvasState. 31 * Defines three mandatory callbacks. 32 */ 33class CanvasStateClient { 34public: 35 CanvasStateClient() { } 36 virtual ~CanvasStateClient() { } 37 38 /** 39 * Callback allowing embedder to take actions in the middle of a 40 * setViewport() call. 41 */ 42 virtual void onViewportInitialized() = 0; 43 44 /** 45 * Callback allowing embedder to take actions in the middle of a 46 * restore() call. May be called several times sequentially. 47 */ 48 virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; 49 50 /** 51 * Allows subclasses to control what value is stored in snapshot's 52 * fbo field in * initializeSaveStack. 53 */ 54 virtual GLuint onGetTargetFbo() const = 0; 55 56}; // class CanvasStateClient 57 58/** 59 * Implements Canvas state methods on behalf of Renderers. 60 * 61 * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the 62 * Renderer interface. Drawing and recording classes that include a CanvasState will have 63 * different use cases: 64 * 65 * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into 66 * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. 67 * 68 * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations 69 * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so 70 * that quickRejection can also be used. 71 */ 72 73class ANDROID_API CanvasState { 74public: 75 CanvasState(CanvasStateClient& renderer); 76 ~CanvasState(); 77 78 /** 79 * Initializes the first snapshot, computing the projection matrix, 80 * and stores the dimensions of the render target. 81 */ 82 void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, 83 const Vector3& lightCenter); 84 85 void setViewport(int width, int height); 86 87 bool hasRectToRectTransform() const { 88 return CC_LIKELY(currentTransform()->rectToRect()); 89 } 90 91 // Save (layer) 92 int getSaveCount() const { return mSaveCount; } 93 int save(int flags); 94 void restore(); 95 void restoreToCount(int saveCount); 96 97 // Save/Restore without side-effects 98 int saveSnapshot(int flags); 99 void restoreSnapshot(); 100 101 // Matrix 102 void getMatrix(SkMatrix* outMatrix) const; 103 void translate(float dx, float dy, float dz = 0.0f); 104 void rotate(float degrees); 105 void scale(float sx, float sy); 106 void skew(float sx, float sy); 107 108 void setMatrix(const SkMatrix& matrix); 109 void setMatrix(const Matrix4& matrix); // internal only convenience method 110 void concatMatrix(const SkMatrix& matrix); 111 void concatMatrix(const Matrix4& matrix); // internal only convenience method 112 113 // Clip 114 const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } 115 const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } 116 117 bool quickRejectConservative(float left, float top, float right, float bottom) const; 118 119 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 120 bool clipPath(const SkPath* path, SkRegion::Op op); 121 bool clipRegion(const SkRegion* region, SkRegion::Op op); 122 123 bool isCurrentClipSimple() const { 124 return currentSnapshot()->clipRegion->isEmpty(); 125 } 126 127 /** 128 * Sets a "clipping outline", which is independent from the regular clip. 129 * Currently only supports rectangles or rounded rectangles; passing in a 130 * more complicated outline fails silently. Replaces any previous clipping 131 * outline. 132 */ 133 void setClippingOutline(LinearAllocator& allocator, const Outline* outline); 134 void setClippingRoundRect(LinearAllocator& allocator, 135 const Rect& rect, float radius, bool highPriority = true); 136 137 /** 138 * Returns true if drawing in the rectangle (left, top, right, bottom) 139 * will be clipped out. Is conservative: might return false when subpixel- 140 * perfect tests would return true. 141 */ 142 bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, 143 bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; 144 145 void setDirtyClip(bool opaque) { mDirtyClip = opaque; } 146 bool getDirtyClip() const { return mDirtyClip; } 147 148 void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } 149 void setEmpty(bool value) { mSnapshot->empty = value; } 150 void setInvisible(bool value) { mSnapshot->invisible = value; } 151 152 inline const mat4* currentTransform() const { return currentSnapshot()->transform; } 153 inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; } 154 inline Region* currentRegion() const { return currentSnapshot()->region; } 155 inline int currentFlags() const { return currentSnapshot()->flags; } 156 const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } 157 inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } 158 int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } 159 int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } 160 int getWidth() { return mWidth; } 161 int getHeight() { return mHeight; } 162 163 inline const Snapshot* currentSnapshot() const { 164 return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get(); 165 } 166 inline Snapshot* writableSnapshot() { return mSnapshot.get(); } 167 inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } 168 169private: 170 /// No default constructor - must supply a CanvasStateClient (mCanvas). 171 CanvasState(); 172 173 /// indicates that the clip has been changed since the last time it was consumed 174 bool mDirtyClip; 175 176 /// Dimensions of the drawing surface 177 int mWidth, mHeight; 178 179 /// Number of saved states 180 int mSaveCount; 181 182 /// Base state 183 sp<Snapshot> mFirstSnapshot; 184 185 /// Host providing callbacks 186 CanvasStateClient& mCanvas; 187 188 /// Current state 189 sp<Snapshot> mSnapshot; 190 191}; // class CanvasState 192 193}; // namespace uirenderer 194}; // namespace android 195 196#endif // ANDROID_HWUI_CANVAS_STATE_H 197