diff options
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Android.mk | 1 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 4 | ||||
-rw-r--r-- | libs/hwui/Snapshot.cpp | 154 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 138 |
4 files changed, 193 insertions, 104 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 95e0a18..5ec3983 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -26,6 +26,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) ShapeCache.cpp \ SkiaColorFilter.cpp \ SkiaShader.cpp \ + Snapshot.cpp \ TextureCache.cpp \ TextDropShadowCache.cpp diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 71fb8da..7854729 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -38,8 +38,8 @@ #define LAYER_SIZE 64 // Defines the size in bits of the stencil buffer -// Note: We only want 1 bit, but in practice we'll get 8 bits on all GPUs -// for the foreseeable future +// Note: Only 1 bit is required for clipping but more bits are required +// to properly implement the winding fill rule when rasterizing paths #define STENCIL_BUFFER_SIZE 0 /** diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp new file mode 100644 index 0000000..a85362d --- /dev/null +++ b/libs/hwui/Snapshot.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Snapshot.h" + +#include <SkCanvas.h> + +namespace android { +namespace uirenderer { + +/////////////////////////////////////////////////////////////////////////////// +// Constructors +/////////////////////////////////////////////////////////////////////////////// + +Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), + invisible(false), empty(false) { + + transform = &mTransformRoot; + clipRect = &mClipRectRoot; + region = NULL; +} + +/** + * Copies the specified snapshot/ The specified snapshot is stored as + * the previous snapshot. + */ +Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): + flags(0), previous(s), layer(NULL), fbo(s->fbo), + invisible(s->invisible), empty(false), + viewport(s->viewport), height(s->height) { + + if (saveFlags & SkCanvas::kMatrix_SaveFlag) { + mTransformRoot.load(*s->transform); + transform = &mTransformRoot; + } else { + transform = s->transform; + } + + if (saveFlags & SkCanvas::kClip_SaveFlag) { + mClipRectRoot.set(*s->clipRect); + clipRect = &mClipRectRoot; + } else { + clipRect = s->clipRect; + } + + if (s->flags & Snapshot::kFlagFboTarget) { + flags |= Snapshot::kFlagFboTarget; + region = s->region; + } else { + region = NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Clipping +/////////////////////////////////////////////////////////////////////////////// + +bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) { + Rect r(left, top, right, bottom); + transform->mapRect(r); + return clipTransformed(r, op); +} + +bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { + bool clipped = false; + + // NOTE: The unimplemented operations require support for regions + // Supporting regions would require using a stencil buffer instead + // of the scissor. The stencil buffer itself is not too expensive + // (memory cost excluded) but on fillrate limited devices, managing + // the stencil might have a negative impact on the framerate. + switch (op) { + case SkRegion::kDifference_Op: + break; + case SkRegion::kIntersect_Op: + clipped = clipRect->intersect(r); + if (!clipped) { + clipRect->setEmpty(); + clipped = true; + } + break; + case SkRegion::kUnion_Op: + clipped = clipRect->unionWith(r); + break; + case SkRegion::kXOR_Op: + break; + case SkRegion::kReverseDifference_Op: + break; + case SkRegion::kReplace_Op: + clipRect->set(r); + clipped = true; + break; + } + + if (clipped) { + flags |= Snapshot::kFlagClipSet; + } + + return clipped; +} + +void Snapshot::setClip(float left, float top, float right, float bottom) { + clipRect->set(left, top, right, bottom); + flags |= Snapshot::kFlagClipSet; +} + +const Rect& Snapshot::getLocalClip() { + mat4 inverse; + inverse.loadInverse(*transform); + + mLocalClip.set(*clipRect); + inverse.mapRect(mLocalClip); + + return mLocalClip; +} + +void Snapshot::resetClip(float left, float top, float right, float bottom) { + clipRect = &mClipRectRoot; + clipRect->set(left, top, right, bottom); + flags |= Snapshot::kFlagClipSet; +} + +/////////////////////////////////////////////////////////////////////////////// +// Transforms +/////////////////////////////////////////////////////////////////////////////// + +void Snapshot::resetTransform(float x, float y, float z) { + transform = &mTransformRoot; + transform->loadTranslate(x, y, z); +} + +/////////////////////////////////////////////////////////////////////////////// +// Queries +/////////////////////////////////////////////////////////////////////////////// + +bool Snapshot::isIgnored() const { + return invisible || empty; +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index aff7b93..c94af7e 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -23,7 +23,7 @@ #include <utils/RefBase.h> #include <ui/Region.h> -#include <SkCanvas.h> +#include <SkRegion.h> #include "Layer.h" #include "Matrix.h" @@ -43,43 +43,12 @@ namespace uirenderer { */ class Snapshot: public LightRefBase<Snapshot> { public: - Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false), empty(false) { - transform = &mTransformRoot; - clipRect = &mClipRectRoot; - region = NULL; - } - /** - * Copies the specified snapshot/ The specified snapshot is stored as - * the previous snapshot. - */ - Snapshot(const sp<Snapshot>& s, int saveFlags): - flags(0), previous(s), layer(NULL), fbo(s->fbo), - invisible(s->invisible), empty(false), viewport(s->viewport), height(s->height) { - if (saveFlags & SkCanvas::kMatrix_SaveFlag) { - mTransformRoot.load(*s->transform); - transform = &mTransformRoot; - } else { - transform = s->transform; - } - - if (saveFlags & SkCanvas::kClip_SaveFlag) { - mClipRectRoot.set(*s->clipRect); - clipRect = &mClipRectRoot; - } else { - clipRect = s->clipRect; - } - - if (s->flags & Snapshot::kFlagFboTarget) { - flags |= Snapshot::kFlagFboTarget; - region = s->region; - } else { - region = NULL; - } - } + Snapshot(); + Snapshot(const sp<Snapshot>& s, int saveFlags); /** - * Various flags set on #flags. + * Various flags set on ::flags. */ enum Flags { /** @@ -115,87 +84,41 @@ public: * by this snapshot's trasnformation. */ bool clip(float left, float top, float right, float bottom, - SkRegion::Op op = SkRegion::kIntersect_Op) { - Rect r(left, top, right, bottom); - transform->mapRect(r); - return clipTransformed(r, op); - } + SkRegion::Op op = SkRegion::kIntersect_Op); /** * Modifies the current clip with the new clip rectangle and * the specified operation. The specified rectangle is considered * already transformed. */ - bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) { - bool clipped = false; - - // NOTE: The unimplemented operations require support for regions - // Supporting regions would require using a stencil buffer instead - // of the scissor. The stencil buffer itself is not too expensive - // (memory cost excluded) but on fillrate limited devices, managing - // the stencil might have a negative impact on the framerate. - switch (op) { - case SkRegion::kDifference_Op: - break; - case SkRegion::kIntersect_Op: - clipped = clipRect->intersect(r); - if (!clipped) { - clipRect->setEmpty(); - clipped = true; - } - break; - case SkRegion::kUnion_Op: - clipped = clipRect->unionWith(r); - break; - case SkRegion::kXOR_Op: - break; - case SkRegion::kReverseDifference_Op: - break; - case SkRegion::kReplace_Op: - clipRect->set(r); - clipped = true; - break; - } - - if (clipped) { - flags |= Snapshot::kFlagClipSet; - } - - return clipped; - } + bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op); /** * Sets the current clip. */ - void setClip(float left, float top, float right, float bottom) { - clipRect->set(left, top, right, bottom); - flags |= Snapshot::kFlagClipSet; - } - - const Rect& getLocalClip() { - mat4 inverse; - inverse.loadInverse(*transform); + void setClip(float left, float top, float right, float bottom); - mLocalClip.set(*clipRect); - inverse.mapRect(mLocalClip); - - return mLocalClip; - } + /** + * Returns the current clip in local coordinates. The clip rect is + * transformed by the inverse transform matrix. + */ + const Rect& getLocalClip(); - void resetTransform(float x, float y, float z) { - transform = &mTransformRoot; - transform->loadTranslate(x, y, z); - } + /** + * Resets the clip to the specified rect. + */ + void resetClip(float left, float top, float right, float bottom); - void resetClip(float left, float top, float right, float bottom) { - clipRect = &mClipRectRoot; - clipRect->set(left, top, right, bottom); - flags |= Snapshot::kFlagClipSet; - } + /** + * Resets the current transform to a pure 3D translation. + */ + void resetTransform(float x, float y, float z); - bool isIgnored() const { - return invisible || empty; - } + /** + * Indicates whether this snapshot should be ignored. A snapshot + * is typicalled ignored if its layer is invisible or empty. + */ + bool isIgnored() const; /** * Dirty flags. @@ -209,6 +132,8 @@ public: /** * Only set when the flag kFlagIsLayer is set. + * + * This snapshot does not own the layer, this pointer must not be freed. */ Layer* layer; @@ -249,17 +174,26 @@ public: /** * Local transformation. Holds the current translation, scale and * rotation values. + * + * This is a reference to a matrix owned by this snapshot or another + * snapshot. This pointer must not be freed. See ::mTransformRoot. */ mat4* transform; /** * Current clip region. The clip is stored in canvas-space coordinates, * (screen-space coordinates in the regular case.) + * + * This is a reference to a rect owned by this snapshot or another + * snapshot. This pointer must not be freed. See ::mClipRectRoot. */ Rect* clipRect; /** * The ancestor layer's dirty region. + * + * This is a reference to a region owned by a layer. This pointer must + * not be freed. */ Region* region; |