Snapshot.h revision f607bdc167f66b3e7003acaa4736ae46d78c1492
15cbbce535744b89df5ecea95de21ee3733298260Romain Guy/*
25cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Copyright (C) 2010 The Android Open Source Project
35cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
45cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
55cbbce535744b89df5ecea95de21ee3733298260Romain Guy * you may not use this file except in compliance with the License.
65cbbce535744b89df5ecea95de21ee3733298260Romain Guy * You may obtain a copy of the License at
75cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
85cbbce535744b89df5ecea95de21ee3733298260Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
95cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
105cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Unless required by applicable law or agreed to in writing, software
115cbbce535744b89df5ecea95de21ee3733298260Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
125cbbce535744b89df5ecea95de21ee3733298260Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135cbbce535744b89df5ecea95de21ee3733298260Romain Guy * See the License for the specific language governing permissions and
145cbbce535744b89df5ecea95de21ee3733298260Romain Guy * limitations under the License.
155cbbce535744b89df5ecea95de21ee3733298260Romain Guy */
165cbbce535744b89df5ecea95de21ee3733298260Romain Guy
175cbbce535744b89df5ecea95de21ee3733298260Romain Guy#ifndef ANDROID_UI_SNAPSHOT_H
185cbbce535744b89df5ecea95de21ee3733298260Romain Guy#define ANDROID_UI_SNAPSHOT_H
195cbbce535744b89df5ecea95de21ee3733298260Romain Guy
205cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include <GLES2/gl2.h>
215cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include <GLES2/gl2ext.h>
225cbbce535744b89df5ecea95de21ee3733298260Romain Guy
235cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include <utils/RefBase.h>
245cbbce535744b89df5ecea95de21ee3733298260Romain Guy
258aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy#include <SkCanvas.h>
26079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <SkRegion.h>
27079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
28dda570201ac851dd85af3861f7e575721d3345daRomain Guy#include "Layer.h"
295cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "Matrix.h"
305cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "Rect.h"
315cbbce535744b89df5ecea95de21ee3733298260Romain Guy
325cbbce535744b89df5ecea95de21ee3733298260Romain Guynamespace android {
335cbbce535744b89df5ecea95de21ee3733298260Romain Guynamespace uirenderer {
345cbbce535744b89df5ecea95de21ee3733298260Romain Guy
355cbbce535744b89df5ecea95de21ee3733298260Romain Guy/**
365cbbce535744b89df5ecea95de21ee3733298260Romain Guy * A snapshot holds information about the current state of the rendering
375cbbce535744b89df5ecea95de21ee3733298260Romain Guy * surface. A snapshot is usually created whenever the user calls save()
385cbbce535744b89df5ecea95de21ee3733298260Romain Guy * and discarded when the user calls restore(). Once a snapshot is created,
395cbbce535744b89df5ecea95de21ee3733298260Romain Guy * it can hold information for deferred rendering.
405cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
415cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Each snapshot has a link to a previous snapshot, indicating the previous
425cbbce535744b89df5ecea95de21ee3733298260Romain Guy * state of the renderer.
435cbbce535744b89df5ecea95de21ee3733298260Romain Guy */
445cbbce535744b89df5ecea95de21ee3733298260Romain Guyclass Snapshot: public LightRefBase<Snapshot> {
455cbbce535744b89df5ecea95de21ee3733298260Romain Guypublic:
46f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    Snapshot(): flags(0), previous(NULL), layer(NULL) {
478aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        transform = &mTransformRoot;
488aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        clipRect = &mClipRectRoot;
498aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    }
505cbbce535744b89df5ecea95de21ee3733298260Romain Guy
515cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
528aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Copies the specified snapshot/ The specified snapshot is stored as
538aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * the previous snapshot.
545cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
558aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Snapshot(const sp<Snapshot>& s, int saveFlags):
56f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy            flags(0), previous(s), layer(NULL) {
578aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
588aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mTransformRoot.load(*s->transform);
598aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            transform = &mTransformRoot;
608aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        } else {
618aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            transform = s->transform;
628aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
638aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
648aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        if (saveFlags & SkCanvas::kClip_SaveFlag) {
658aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mClipRectRoot.set(*s->clipRect);
668aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            clipRect = &mClipRectRoot;
678aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        } else {
688aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            clipRect = s->clipRect;
698aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
708aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
71b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        if ((s->flags & Snapshot::kFlagClipSet) &&
72b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy                !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
738aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mLocalClip.set(s->mLocalClip);
74b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        } else {
75b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            flags |= Snapshot::kFlagDirtyLocalClip;
76b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        }
775cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
785cbbce535744b89df5ecea95de21ee3733298260Romain Guy
795cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
805cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Various flags set on #flags.
815cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
825cbbce535744b89df5ecea95de21ee3733298260Romain Guy    enum Flags {
835cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
845cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that the clip region was modified. When this
855cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * snapshot is restored so must the clip.
865cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
875cbbce535744b89df5ecea95de21ee3733298260Romain Guy        kFlagClipSet = 0x1,
885cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
895cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that this snapshot was created when saving
905cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * a new layer.
915cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
92079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        kFlagIsLayer = 0x2,
93f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy        /**
9409147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         * Indicates that the local clip should be recomputed.
9509147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         */
96f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        kFlagDirtyLocalClip = 0x4,
975cbbce535744b89df5ecea95de21ee3733298260Romain Guy    };
985cbbce535744b89df5ecea95de21ee3733298260Romain Guy
995cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
100f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * Modifies the current clip with the new clip rectangle and
101f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * the specified operation. The specified rectangle is transformed
102f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * by this snapshot's trasnformation.
1033d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy     */
104f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    bool clip(float left, float top, float right, float bottom,
105f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy            SkRegion::Op op = SkRegion::kIntersect_Op) {
106af28b514964861d81b48902f942f706050936d38Romain Guy        Rect r(left, top, right, bottom);
1078aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        transform->mapRect(r);
108f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        return clipTransformed(r, op);
109f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    }
110f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
111f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    /**
112f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * Modifies the current clip with the new clip rectangle and
113f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * the specified operation. The specified rectangle is considered
114f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     * already transformed.
115f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy     */
116f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) {
117f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        bool clipped = false;
118079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
119079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        switch (op) {
1207fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kDifference_Op:
1217fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1227fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kIntersect_Op:
1238aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipped = clipRect->intersect(r);
1247fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1257fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kUnion_Op:
1268aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipped = clipRect->unionWith(r);
1277fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1287fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kXOR_Op:
1297fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1307fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReverseDifference_Op:
1317fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1327fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReplace_Op:
1338aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipRect->set(r);
1347fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipped = true;
1357fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1365cbbce535744b89df5ecea95de21ee3733298260Romain Guy        }
137079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
138079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (clipped) {
13909147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
141079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1423d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy        return clipped;
1435cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
1445cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1455cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
146d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     * Sets the current clip.
147d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     */
148d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    void setClip(float left, float top, float right, float bottom) {
1498aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        clipRect->set(left, top, right, bottom);
15009147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
151079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
152079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
153079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    const Rect& getLocalClip() {
15409147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        if (flags & Snapshot::kFlagDirtyLocalClip) {
15509147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            mat4 inverse;
1568aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            inverse.loadInverse(*transform);
157959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
1588aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mLocalClip.set(*clipRect);
1598aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            inverse.mapRect(mLocalClip);
160959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
16109147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags &= ~Snapshot::kFlagDirtyLocalClip;
16209147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        }
1638aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        return mLocalClip;
164d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    }
165d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy
1668b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    /**
1675cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Dirty flags.
1685cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1695cbbce535744b89df5ecea95de21ee3733298260Romain Guy    int flags;
1705cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1715cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1725cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Previous snapshot.
1735cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1745cbbce535744b89df5ecea95de21ee3733298260Romain Guy    sp<Snapshot> previous;
1755cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1765cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1775cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Only set when the flag kFlagIsLayer is set.
1785cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
179dda570201ac851dd85af3861f7e575721d3345daRomain Guy    Layer* layer;
180f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
1818aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    /**
1828aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Local transformation. Holds the current translation, scale and
1838aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * rotation values.
1848aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     */
1858aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    mat4* transform;
1868aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
1878aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    /**
1888aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Current clip region. The clip is stored in canvas-space coordinates,
1898aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * (screen-space coordinates in the regular case.)
1908aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     */
1918aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect* clipRect;
1928aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
1935cbbce535744b89df5ecea95de21ee3733298260Romain Guyprivate:
1948aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    mat4 mTransformRoot;
1958aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect mClipRectRoot;
1968aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect mLocalClip;
197079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1985cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // class Snapshot
1995cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2005cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace uirenderer
2015cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace android
2025cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2035cbbce535744b89df5ecea95de21ee3733298260Romain Guy#endif // ANDROID_UI_SNAPSHOT_H
204