Snapshot.h revision 8aef54fa17f2a3753d9a8f2027629bc480088f69
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:
468aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) {
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):
56f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy            height(s->height),
578b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy            invisible(s->invisible),
5809147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags(0),
595cbbce535744b89df5ecea95de21ee3733298260Romain Guy            previous(s),
60dda570201ac851dd85af3861f7e575721d3345daRomain Guy            layer(NULL),
611d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy            fbo(s->fbo),
621d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy            viewport(s->viewport) {
638aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
648aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mTransformRoot.load(*s->transform);
658aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            transform = &mTransformRoot;
668aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        } else {
678aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            transform = s->transform;
688aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
698aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
708aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        if (saveFlags & SkCanvas::kClip_SaveFlag) {
718aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mClipRectRoot.set(*s->clipRect);
728aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            clipRect = &mClipRectRoot;
738aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        } else {
748aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            clipRect = s->clipRect;
758aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
768aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
77b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        if ((s->flags & Snapshot::kFlagClipSet) &&
78b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy                !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
798aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mLocalClip.set(s->mLocalClip);
80b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        } else {
81b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            flags |= Snapshot::kFlagDirtyLocalClip;
82b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy        }
835cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
845cbbce535744b89df5ecea95de21ee3733298260Romain Guy
855cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
865cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Various flags set on #flags.
875cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
885cbbce535744b89df5ecea95de21ee3733298260Romain Guy    enum Flags {
895cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
905cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that the clip region was modified. When this
915cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * snapshot is restored so must the clip.
925cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
935cbbce535744b89df5ecea95de21ee3733298260Romain Guy        kFlagClipSet = 0x1,
945cbbce535744b89df5ecea95de21ee3733298260Romain Guy        /**
955cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * Indicates that this snapshot was created when saving
965cbbce535744b89df5ecea95de21ee3733298260Romain Guy         * a new layer.
975cbbce535744b89df5ecea95de21ee3733298260Romain Guy         */
98079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        kFlagIsLayer = 0x2,
99f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy        /**
100f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy         * Indicates that this snapshot has changed the ortho matrix.
101f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy         */
102079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        kFlagDirtyOrtho = 0x4,
10309147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        /**
10409147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         * Indicates that the local clip should be recomputed.
10509147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy         */
10609147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        kFlagDirtyLocalClip = 0x8,
1075cbbce535744b89df5ecea95de21ee3733298260Romain Guy    };
1085cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1095cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1103d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy     * Intersects the current clip with the new clip rectangle.
1113d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy     */
112079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    bool clip(float left, float top, float right, float bottom, SkRegion::Op op) {
113079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        bool clipped = false;
114079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
115af28b514964861d81b48902f942f706050936d38Romain Guy        Rect r(left, top, right, bottom);
1168aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        transform->mapRect(r);
117079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
118079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        switch (op) {
1197fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kDifference_Op:
1207fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1217fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kIntersect_Op:
1228aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipped = clipRect->intersect(r);
1237fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1247fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kUnion_Op:
1258aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipped = clipRect->unionWith(r);
1267fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1277fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kXOR_Op:
1287fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1297fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReverseDifference_Op:
1307fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1317fac2e18339f765320d759e8d4c090f92431959eRomain Guy            case SkRegion::kReplace_Op:
1328aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy                clipRect->set(r);
1337fac2e18339f765320d759e8d4c090f92431959eRomain Guy                clipped = true;
1347fac2e18339f765320d759e8d4c090f92431959eRomain Guy                break;
1355cbbce535744b89df5ecea95de21ee3733298260Romain Guy        }
136079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
137079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (clipped) {
13809147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
139079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1413d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy        return clipped;
1425cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
1435cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1445cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
145d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     * Sets the current clip.
146d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy     */
147d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    void setClip(float left, float top, float right, float bottom) {
1488aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        clipRect->set(left, top, right, bottom);
14909147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
150079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
151079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
152079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    const Rect& getLocalClip() {
15309147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        if (flags & Snapshot::kFlagDirtyLocalClip) {
15409147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            mat4 inverse;
1558aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            inverse.loadInverse(*transform);
156959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
1578aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            mLocalClip.set(*clipRect);
1588aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            inverse.mapRect(mLocalClip);
159959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain Guy
16009147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy            flags &= ~Snapshot::kFlagDirtyLocalClip;
16109147fbdc8206a0cac78bfe9083e7e15b3c5689cRomain Guy        }
1628aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        return mLocalClip;
163d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    }
164d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy
1658aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    // TODO: Temporary
1668aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    void resetTransform(float x, float y, float z) {
1678aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        transform = &mTransformRoot;
1688aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        transform->loadTranslate(x, y, z);
1698aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    }
170f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
1718aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    // TODO: Temporary
1728aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    void resetClip(float left, float top, float right, float bottom) {
1738aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        clipRect = &mClipRectRoot;
1748aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        clipRect->set(left, top, right, bottom);
1758aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
1768aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    }
1775cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1785cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1798aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Height of the framebuffer the snapshot is rendering into.
1805cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1818aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    int height;
1825cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1835cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1848b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy     * If true, the layer won't be rendered.
1858b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy     */
1868b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    bool invisible;
1878b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy
1888b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    /**
1895cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Dirty flags.
1905cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1915cbbce535744b89df5ecea95de21ee3733298260Romain Guy    int flags;
1925cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1935cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1945cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Previous snapshot.
1955cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
1965cbbce535744b89df5ecea95de21ee3733298260Romain Guy    sp<Snapshot> previous;
1975cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1985cbbce535744b89df5ecea95de21ee3733298260Romain Guy    /**
1995cbbce535744b89df5ecea95de21ee3733298260Romain Guy     * Only set when the flag kFlagIsLayer is set.
2005cbbce535744b89df5ecea95de21ee3733298260Romain Guy     */
201dda570201ac851dd85af3861f7e575721d3345daRomain Guy    Layer* layer;
2025cbbce535744b89df5ecea95de21ee3733298260Romain Guy    GLuint fbo;
2035cbbce535744b89df5ecea95de21ee3733298260Romain Guy
204f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    /**
2051d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy     * Current viewport.
2061d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy     */
2071d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    Rect viewport;
2081d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy
2091d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    /**
210f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     * Contains the previous ortho matrix.
211f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy     */
212260e102162322958cf17dbd895cd6bd30dc87e32Romain Guy    mat4 orthoMatrix;
213f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
2148aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    /**
2158aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Local transformation. Holds the current translation, scale and
2168aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * rotation values.
2178aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     */
2188aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    mat4* transform;
2198aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
2208aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    /**
2218aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * Current clip region. The clip is stored in canvas-space coordinates,
2228aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     * (screen-space coordinates in the regular case.)
2238aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy     */
2248aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect* clipRect;
2258aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
2265cbbce535744b89df5ecea95de21ee3733298260Romain Guyprivate:
2278aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    mat4 mTransformRoot;
2288aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect mClipRectRoot;
2298aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect mLocalClip;
230079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
2315cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // class Snapshot
2325cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2335cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace uirenderer
2345cbbce535744b89df5ecea95de21ee3733298260Romain Guy}; // namespace android
2355cbbce535744b89df5ecea95de21ee3733298260Romain Guy
2365cbbce535744b89df5ecea95de21ee3733298260Romain Guy#endif // ANDROID_UI_SNAPSHOT_H
237