diff options
Diffstat (limited to 'libs/hwui/CanvasState.h')
-rw-r--r-- | libs/hwui/CanvasState.h | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h new file mode 100644 index 0000000..6883d0a --- /dev/null +++ b/libs/hwui/CanvasState.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_CANVAS_STATE_H +#define ANDROID_HWUI_CANVAS_STATE_H + +#include <SkMatrix.h> +#include <SkPath.h> +#include <SkRegion.h> + +#include "Snapshot.h" + +namespace android { +namespace uirenderer { + +/** + * Abstract base class for any class containing CanvasState. + * Defines three mandatory callbacks. + */ +class CanvasStateClient { +public: + CanvasStateClient() { } + virtual ~CanvasStateClient() { } + + /** + * Callback allowing embedder to take actions in the middle of a + * setViewport() call. + */ + virtual void onViewportInitialized() = 0; + + /** + * Callback allowing embedder to take actions in the middle of a + * restore() call. May be called several times sequentially. + */ + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; + + /** + * Allows subclasses to control what value is stored in snapshot's + * fbo field in * initializeSaveStack. + */ + virtual GLuint onGetTargetFbo() const = 0; + +}; // class CanvasStateClient + +/** + * Implements Canvas state methods on behalf of Renderers. + * + * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the + * Renderer interface. Drawing and recording classes that include a CanvasState will have + * different use cases: + * + * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into + * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. + * + * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations + * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so + * that quickRejection can also be used. + */ + +class ANDROID_API CanvasState { +public: + CanvasState(CanvasStateClient& renderer); + ~CanvasState(); + + /** + * Initializes the first snapshot, computing the projection matrix, + * and stores the dimensions of the render target. + */ + void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, + const Vector3& lightCenter); + + void setViewport(int width, int height); + + bool hasRectToRectTransform() const { + return CC_LIKELY(currentTransform()->rectToRect()); + } + + // Save (layer) + int getSaveCount() const { return mSaveCount; } + int save(int flags); + void restore(); + void restoreToCount(int saveCount); + + // Save/Restore without side-effects + int saveSnapshot(int flags); + void restoreSnapshot(); + + // Matrix + void getMatrix(SkMatrix* outMatrix) const; + void translate(float dx, float dy, float dz = 0.0f); + void rotate(float degrees); + void scale(float sx, float sy); + void skew(float sx, float sy); + + void setMatrix(const SkMatrix& matrix); + void setMatrix(const Matrix4& matrix); // internal only convenience method + void concatMatrix(const SkMatrix& matrix); + void concatMatrix(const Matrix4& matrix); // internal only convenience method + + // Clip + const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } + const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } + + bool quickRejectConservative(float left, float top, float right, float bottom) const; + + bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); + bool clipPath(const SkPath* path, SkRegion::Op op); + bool clipRegion(const SkRegion* region, SkRegion::Op op); + + bool isCurrentClipSimple() const { + return currentSnapshot()->clipRegion->isEmpty(); + } + + /** + * Sets a "clipping outline", which is independent from the regular clip. + * Currently only supports rectangles or rounded rectangles; passing in a + * more complicated outline fails silently. Replaces any previous clipping + * outline. + */ + void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority = true); + + /** + * Returns true if drawing in the rectangle (left, top, right, bottom) + * will be clipped out. Is conservative: might return false when subpixel- + * perfect tests would return true. + */ + bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, + bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; + + void setDirtyClip(bool opaque) { mDirtyClip = opaque; } + bool getDirtyClip() const { return mDirtyClip; } + + void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } + void setEmpty(bool value) { mSnapshot->empty = value; } + void setInvisible(bool value) { mSnapshot->invisible = value; } + + inline const mat4* currentTransform() const { return currentSnapshot()->transform; } + inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; } + inline Region* currentRegion() const { return currentSnapshot()->region; } + inline int currentFlags() const { return currentSnapshot()->flags; } + const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } + inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } + int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } + int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } + int getWidth() { return mWidth; } + int getHeight() { return mHeight; } + + inline const Snapshot* currentSnapshot() const { + return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get(); + } + inline Snapshot* writableSnapshot() { return mSnapshot.get(); } + inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } + +private: + /// No default constructor - must supply a CanvasStateClient (mCanvas). + CanvasState(); + + /// indicates that the clip has been changed since the last time it was consumed + bool mDirtyClip; + + /// Dimensions of the drawing surface + int mWidth, mHeight; + + /// Number of saved states + int mSaveCount; + + /// Base state + sp<Snapshot> mFirstSnapshot; + + /// Host providing callbacks + CanvasStateClient& mCanvas; + + /// Current state + sp<Snapshot> mSnapshot; + +}; // class CanvasState + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_CANVAS_STATE_H |