Snapshot.h revision 959c91f7f7b4f921d341264f5b4ef54e702a0df0
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
25079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <SkRegion.h>
26079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
27dda570201ac851dd85af3861f7e575721d3345daRomain Guy#include "Layer.h"
285cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "Matrix.h"
295cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "Rect.h"
305cbbce535744b89df5ecea95de21ee3733298260Romain Guy
315cbbce535744b89df5ecea95de21ee3733298260Romain Guynamespace android {
325cbbce535744b89df5ecea95de21ee3733298260Romain Guynamespace uirenderer {
335cbbce535744b89df5ecea95de21ee3733298260Romain Guy
345cbbce535744b89df5ecea95de21ee3733298260Romain Guy/**
355cbbce535744b89df5ecea95de21ee3733298260Romain Guy * A snapshot holds information about the current state of the rendering
365cbbce535744b89df5ecea95de21ee3733298260Romain Guy * surface. A snapshot is usually created whenever the user calls save()
375cbbce535744b89df5ecea95de21ee3733298260Romain Guy * and discarded when the user calls restore(). Once a snapshot is created,
385cbbce535744b89df5ecea95de21ee3733298260Romain Guy * it can hold information for deferred rendering.
395cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
405cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Each snapshot has a link to a previous snapshot, indicating the previous
415cbbce535744b89df5ecea95de21ee3733298260Romain Guy * state of the renderer.
425cbbce535744b89df5ecea95de21ee3733298260Romain Guy */
435cbbce535744b89df5ecea95de21ee3733298260Romain Guyclass Snapshot: public LightRefBase<Snapshot> {
445cbbce535744b89df5ecea95de21ee3733298260Romain Guypublic:
4509147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) { }
465cbbce535744b89df5ecea95de21ee3733298260Romain Guy
475cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
485cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Copies the specified snapshot. Only the transform and clip rectangle
495cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * are copied. The layer information is set to 0 and the transform is
505cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * assumed to be dirty. The specified snapshot is stored as the previous
515cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * snapshot.
525cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
53ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guy    Snapshot(const sp<Snapshot>& s):
54f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy            height(s->height),
555cbbce535744b89df5ecea95de21ee3733298260Romain Guy            transform(s->transform),
565cbbce535744b89df5ecea95de21ee3733298260Romain Guy            clipRect(s->clipRect),
5709147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags(0),
585cbbce535744b89df5ecea95de21ee3733298260Romain Guy            previous(s),
59dda570201ac851dd85af3861f7e575721d3345daRomain Guy            layer(NULL),
60b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            fbo(s->fbo) {
61b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        if ((s->flags & Snapshot::kFlagClipSet) &&
62b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy                !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
63b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            localClip.set(s->localClip);
64b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        } else {
65b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            flags |= Snapshot::kFlagDirtyLocalClip;
66b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        }
675cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
685cbbce535744b89df5ecea95de21ee3733298260Romain Guy
695cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
705cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Various flags set on #flags.
715cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
725cbbce535744b89df5ecea95de21ee3733298260Romain Guy    enum Flags {
735cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
745cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that the clip region was modified. When this
755cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * snapshot is restored so must the clip.
765cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
775cbbce535744b89df5ecea95de21ee3733298260Romain Guy        kFlagClipSet = 0x1,
785cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
795cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that this snapshot was created when saving
805cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * a new layer.
815cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
82079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        kFlagIsLayer = 0x2,
83f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy        /**
84f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy         * Indicates that this snapshot has changed the ortho matrix.
85f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy         */
86079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        kFlagDirtyOrtho = 0x4,
8709147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        /**
8809147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         * Indicates that the local clip should be recomputed.
8909147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         */
9009147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        kFlagDirtyLocalClip = 0x8,
915cbbce535744b89df5ecea95de21ee3733298260Romain Guy    };
925cbbce535744b89df5ecea95de21ee3733298260Romain Guy
935cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
943d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy     * Intersects the current clip with the new clip rectangle.
953d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy     */
96079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    bool clip(float left, float top, float right, float bottom, SkRegion::Op op) {
97079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        bool clipped = false;
98079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
99959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        SkRect sr;
100959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        sr.set(left, top, right, bottom);
101079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
102959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        SkMatrix m;
103959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        transform.copyTo(m);
104959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        m.mapRect(&sr);
105959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
106959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy        Rect r(sr.fLeft, sr.fTop, sr.fRight, sr.fBottom);
107079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        switch (op) {
1087fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kDifference_Op:
1097fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1107fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kIntersect_Op:
1117fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipped = clipRect.intersect(r);
1127fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1137fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kUnion_Op:
1147fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipped = clipRect.unionWith(r);
1157fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1167fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kXOR_Op:
1177fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1187fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReverseDifference_Op:
1197fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1207fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReplace_Op:
1217fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipRect.set(r);
1227fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipped = true;
1237fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1245cbbce535744b89df5ecea95de21ee3733298260Romain Guy        }
125079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
126079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (clipped) {
12709147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
128079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
129079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1303d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy        return clipped;
1315cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
1325cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1335cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
134d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     * Sets the current clip.
135d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     */
136d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    void setClip(float left, float top, float right, float bottom) {
137d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        clipRect.set(left, top, right, bottom);
13809147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
139079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
141079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    const Rect& getLocalClip() {
14209147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        if (flags & Snapshot::kFlagDirtyLocalClip) {
14309147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            mat4 inverse;
14409147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            inverse.loadInverse(transform);
145959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
146959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            SkRect sr;
147959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            sr.set(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
148959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
149959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            SkMatrix m;
150959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            inverse.copyTo(m);
151959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            m.mapRect(&sr);
152959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
153959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy            localClip.set(sr.fLeft, sr.fTop, sr.fRight, sr.fBottom);
154959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
15509147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags &= ~Snapshot::kFlagDirtyLocalClip;
15609147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        }
157079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return localClip;
158d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    }
159d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy
160d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    /**
161f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     * Height of the framebuffer the snapshot is rendering into.
162f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     */
163f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    int height;
164f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
165f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    /**
1665cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Local transformation. Holds the current translation, scale and
1675cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * rotation values.
1685cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1695cbbce535744b89df5ecea95de21ee3733298260Romain Guy    mat4 transform;
1705cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1715cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
172079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy     * Current clip region. The clip is stored in canvas-space coordinates,
173079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy     * (screen-space coordinates in the regular case.)
1745cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1755cbbce535744b89df5ecea95de21ee3733298260Romain Guy    Rect clipRect;
1765cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1775cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1785cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Dirty flags.
1795cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1805cbbce535744b89df5ecea95de21ee3733298260Romain Guy    int flags;
1815cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1825cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1835cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Previous snapshot.
1845cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1855cbbce535744b89df5ecea95de21ee3733298260Romain Guy    sp<Snapshot> previous;
1865cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1875cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1885cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Only set when the flag kFlagIsLayer is set.
1895cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
190dda570201ac851dd85af3861f7e575721d3345daRomain Guy    Layer* layer;
1915cbbce535744b89df5ecea95de21ee3733298260Romain Guy    GLuint fbo;
1925cbbce535744b89df5ecea95de21ee3733298260Romain Guy
193f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    /**
194f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     * Contains the previous ortho matrix.
195f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     */
196260e102162322958cf17dbd895cd6bd30dc87e32Romain Guy    mat4 orthoMatrix;
197f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
1985cbbce535744b89df5ecea95de21ee3733298260Romain Guyprivate:
199079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    Rect localClip;
200079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
2015cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // class Snapshot
2025cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2035cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace uirenderer
2045cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace android
2055cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2065cbbce535744b89df5ecea95de21ee3733298260Romain Guy#endif // ANDROID_UI_SNAPSHOT_H
207