CanvasState.h revision d9ee550888011a64fa3f35e666360ec8278597d8
1984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/* 2984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Copyright (C) 2014 The Android Open Source Project 3984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 4984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Licensed under the Apache License, Version 2.0 (the "License"); 5984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * you may not use this file except in compliance with the License. 6984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * You may obtain a copy of the License at 7984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 8984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * http://www.apache.org/licenses/LICENSE-2.0 9984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 10984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Unless required by applicable law or agreed to in writing, software 11984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * distributed under the License is distributed on an "AS IS" BASIS, 12984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * See the License for the specific language governing permissions and 14984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * limitations under the License. 15984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 16984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 17984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#ifndef ANDROID_HWUI_CANVAS_STATE_H 18984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#define ANDROID_HWUI_CANVAS_STATE_H 19984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 20d9ee550888011a64fa3f35e666360ec8278597d8John Reck#include "Snapshot.h" 21d9ee550888011a64fa3f35e666360ec8278597d8John Reck 22984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkMatrix.h> 23984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkPath.h> 24984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkRegion.h> 25984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 26984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonnamespace android { 27984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonnamespace uirenderer { 28984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 29984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/** 30984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Abstract base class for any class containing CanvasState. 31984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Defines three mandatory callbacks. 32984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 33984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonclass CanvasStateClient { 34984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonpublic: 35984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson CanvasStateClient() { } 36984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson virtual ~CanvasStateClient() { } 37984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 38984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 39984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Callback allowing embedder to take actions in the middle of a 40984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * setViewport() call. 41984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 42984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson virtual void onViewportInitialized() = 0; 43984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 44984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 45984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Callback allowing embedder to take actions in the middle of a 46984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * restore() call. May be called several times sequentially. 47984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 48984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; 49984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 50984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 51984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Allows subclasses to control what value is stored in snapshot's 52984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * fbo field in * initializeSaveStack. 53984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 546b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik virtual GLuint getTargetFbo() const = 0; 55984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 56984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // class CanvasStateClient 57984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 58984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/** 59984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Implements Canvas state methods on behalf of Renderers. 60984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 61984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the 62984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Renderer interface. Drawing and recording classes that include a CanvasState will have 63984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * different use cases: 64984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 65db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * Drawing code maintaining canvas state (i.e. OpenGLRenderer) can query attributes (such as 66db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * transform) or hook into changes (e.g. save/restore) with minimal surface area for manipulating 67db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * the stack itself. 68984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * 69db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * Recording code maintaining canvas state (i.e. DisplayListCanvas) can both record and pass 70db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * through state operations to CanvasState, so that not only will querying operations work 71db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * (getClip/Matrix), but so that quickRejection can also be used. 72984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 73984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 7464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikclass CanvasState { 75984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonpublic: 76984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson CanvasState(CanvasStateClient& renderer); 77d9ee550888011a64fa3f35e666360ec8278597d8John Reck ~CanvasState(); 78984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 79984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 80984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Initializes the first snapshot, computing the projection matrix, 81984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * and stores the dimensions of the render target. 82984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 8364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik void initializeSaveStack(int viewportWidth, int viewportHeight, 8464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik float clipLeft, float clipTop, float clipRight, float clipBottom, 85984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson const Vector3& lightCenter); 86984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 87984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool hasRectToRectTransform() const { 88984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return CC_LIKELY(currentTransform()->rectToRect()); 89984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson } 90984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 91984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson // Save (layer) 92984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int getSaveCount() const { return mSaveCount; } 93984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int save(int flags); 94984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void restore(); 95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void restoreToCount(int saveCount); 96984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 97984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson // Save/Restore without side-effects 98984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int saveSnapshot(int flags); 99984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void restoreSnapshot(); 100984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 101984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson // Matrix 102984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void getMatrix(SkMatrix* outMatrix) const; 103984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void translate(float dx, float dy, float dz = 0.0f); 104984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void rotate(float degrees); 105984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void scale(float sx, float sy); 106984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void skew(float sx, float sy); 107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 108984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setMatrix(const SkMatrix& matrix); 109984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setMatrix(const Matrix4& matrix); // internal only convenience method 110984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void concatMatrix(const SkMatrix& matrix); 111984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void concatMatrix(const Matrix4& matrix); // internal only convenience method 112984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 113984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson // Clip 114984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } 115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } 116984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 117984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool quickRejectConservative(float left, float top, float right, float bottom) const; 118984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool clipPath(const SkPath* path, SkRegion::Op op); 121984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool clipRegion(const SkRegion* region, SkRegion::Op op); 122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 123984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 124984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Sets a "clipping outline", which is independent from the regular clip. 125984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Currently only supports rectangles or rounded rectangles; passing in a 126984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * more complicated outline fails silently. Replaces any previous clipping 127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * outline. 128984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 129984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setClippingOutline(LinearAllocator& allocator, const Outline* outline); 130984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setClippingRoundRect(LinearAllocator& allocator, 131984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson const Rect& rect, float radius, bool highPriority = true); 132fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path); 133984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 134984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /** 135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Returns true if drawing in the rectangle (left, top, right, bottom) 136984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * will be clipped out. Is conservative: might return false when subpixel- 137984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * perfect tests would return true. 138984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */ 139984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, 140984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; 141984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 142984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setDirtyClip(bool opaque) { mDirtyClip = opaque; } 143984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool getDirtyClip() const { return mDirtyClip; } 144984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 145984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } 146984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setEmpty(bool value) { mSnapshot->empty = value; } 147984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson void setInvisible(bool value) { mSnapshot->invisible = value; } 148984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 149984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson inline const mat4* currentTransform() const { return currentSnapshot()->transform; } 150487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk inline const Rect& currentClipRect() const { return currentSnapshot()->getClipRect(); } 151984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson inline Region* currentRegion() const { return currentSnapshot()->region; } 152984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson inline int currentFlags() const { return currentSnapshot()->flags; } 153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } 154984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } 155984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } 156984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } 157a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik int getWidth() const { return mWidth; } 158a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik int getHeight() const { return mHeight; } 159a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); } 160984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 161d9ee550888011a64fa3f35e666360ec8278597d8John Reck inline const Snapshot* currentSnapshot() const { return mSnapshot; } 162d9ee550888011a64fa3f35e666360ec8278597d8John Reck inline Snapshot* writableSnapshot() { return mSnapshot; } 163d9ee550888011a64fa3f35e666360ec8278597d8John Reck inline const Snapshot* firstSnapshot() const { return &mFirstSnapshot; } 164984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonprivate: 166d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* allocSnapshot(Snapshot* previous, int savecount); 167d9ee550888011a64fa3f35e666360ec8278597d8John Reck void freeSnapshot(Snapshot* snapshot); 168d9ee550888011a64fa3f35e666360ec8278597d8John Reck void freeAllSnapshots(); 169d9ee550888011a64fa3f35e666360ec8278597d8John Reck 170984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// indicates that the clip has been changed since the last time it was consumed 171984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson bool mDirtyClip; 172984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// Dimensions of the drawing surface 174984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int mWidth, mHeight; 175984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 176984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// Number of saved states 177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson int mSaveCount; 178984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 179984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// Base state 180d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot mFirstSnapshot; 181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 182984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// Host providing callbacks 183984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson CanvasStateClient& mCanvas; 184984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 185984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson /// Current state 186d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* mSnapshot; 187d9ee550888011a64fa3f35e666360ec8278597d8John Reck 188d9ee550888011a64fa3f35e666360ec8278597d8John Reck // Pool of allocated snapshots to re-use 189d9ee550888011a64fa3f35e666360ec8278597d8John Reck // NOTE: The dtors have already been invoked! 190d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* mSnapshotPool = nullptr; 191d9ee550888011a64fa3f35e666360ec8278597d8John Reck int mSnapshotPoolCount = 0; 192984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 193984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // class CanvasState 194984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 195984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace uirenderer 196984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace android 197984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 198984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#endif // ANDROID_HWUI_CANVAS_STATE_H 199