summaryrefslogtreecommitdiffstats
path: root/libs/hwui/Snapshot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/Snapshot.cpp')
-rw-r--r--libs/hwui/Snapshot.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 9e7faee..beb2e1d 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -36,6 +36,7 @@ Snapshot::Snapshot()
, empty(false)
, alpha(1.0f)
, roundRectClipState(nullptr)
+ , projectionPathMask(nullptr)
, mClipArea(&mClipAreaRoot) {
transform = &mTransformRoot;
region = nullptr;
@@ -54,6 +55,7 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags)
, empty(false)
, alpha(s->alpha)
, roundRectClipState(s->roundRectClipState)
+ , projectionPathMask(s->projectionPathMask)
, mClipArea(nullptr)
, mViewportData(s->mViewportData)
, mRelativeLightCenter(s->mRelativeLightCenter) {
@@ -141,6 +143,34 @@ void Snapshot::resetTransform(float x, float y, float z) {
transform->loadTranslate(x, y, z);
}
+void Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const {
+ // build (reverse ordered) list of the stack of snapshots, terminated with a NULL
+ Vector<const Snapshot*> snapshotList;
+ snapshotList.push(nullptr);
+ const Snapshot* current = this;
+ do {
+ snapshotList.push(current);
+ current = current->previous.get();
+ } while (current);
+
+ // traverse the list, adding in each transform that contributes to the total transform
+ outTransform->loadIdentity();
+ for (size_t i = snapshotList.size() - 1; i > 0; i--) {
+ // iterate down the stack
+ const Snapshot* current = snapshotList[i];
+ const Snapshot* next = snapshotList[i - 1];
+ if (current->flags & kFlagIsFboLayer) {
+ // if we've hit a layer, translate by the layer's draw offset
+ outTransform->translate(current->layer->layer.left, current->layer->layer.top);
+ }
+ if (!next || (next->flags & kFlagIsFboLayer)) {
+ // if this snapshot is last, or if this snapshot is last before an
+ // FBO layer (which reset the transform), apply it
+ outTransform->multiply(*(current->transform));
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// Clipping round rect
///////////////////////////////////////////////////////////////////////////////
@@ -191,6 +221,18 @@ void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& boun
roundRectClipState = state;
}
+void Snapshot::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
+ if (path) {
+ ProjectionPathMask* mask = new (allocator) ProjectionPathMask;
+ mask->projectionMask = path;
+ buildScreenSpaceTransform(&(mask->projectionMaskTransform));
+
+ projectionPathMask = mask;
+ } else {
+ projectionPathMask = nullptr;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// Queries
///////////////////////////////////////////////////////////////////////////////