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