diff options
Diffstat (limited to 'libs')
96 files changed, 1486 insertions, 1587 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index e78e4fe69ff0..2b8e79287785 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -4640,7 +4640,7 @@ bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) if (len > 0) { return false; } - if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') { + if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') { return false; } diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index 5840107027d5..6ec42c269329 100644 --- a/libs/hwui/AmbientShadow.cpp +++ b/libs/hwui/AmbientShadow.cpp @@ -60,6 +60,7 @@ #include "AmbientShadow.h" #include "ShadowTessellator.h" #include "Vertex.h" +#include "VertexBuffer.h" #include "utils/MathUtils.h" namespace android { diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h index 9660dc03c5fe..8eb1048f4d1c 100644 --- a/libs/hwui/AmbientShadow.h +++ b/libs/hwui/AmbientShadow.h @@ -19,13 +19,13 @@ #define ANDROID_HWUI_AMBIENT_SHADOW_H #include "Debug.h" -#include "OpenGLRenderer.h" #include "Vector.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + /** * AmbientShadow is used to calculate the ambient shadow value around a polygon. */ diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk new file mode 100644 index 000000000000..fba7254e6d74 --- /dev/null +++ b/libs/hwui/Android.common.mk @@ -0,0 +1,103 @@ +# getConfig in external/skia/include/core/SkBitmap.h is deprecated. +# Allow Gnu extension: in-class initializer of static 'const float' member. +LOCAL_CLANG_CFLAGS += \ + -Wno-deprecated-declarations \ + -Wno-gnu-static-float-init + +LOCAL_SRC_FILES := \ + utils/Blur.cpp \ + utils/GLUtils.cpp \ + utils/SortedListImpl.cpp \ + thread/TaskManager.cpp \ + font/CacheTexture.cpp \ + font/Font.cpp \ + AmbientShadow.cpp \ + AnimationContext.cpp \ + Animator.cpp \ + AnimatorManager.cpp \ + AssetAtlas.cpp \ + Caches.cpp \ + CanvasState.cpp \ + DamageAccumulator.cpp \ + DisplayList.cpp \ + DeferredDisplayList.cpp \ + DeferredLayerUpdater.cpp \ + DisplayListLogBuffer.cpp \ + DisplayListRenderer.cpp \ + Dither.cpp \ + DrawProfiler.cpp \ + Extensions.cpp \ + FboCache.cpp \ + FontRenderer.cpp \ + GammaFontRenderer.cpp \ + GradientCache.cpp \ + Image.cpp \ + Interpolator.cpp \ + Layer.cpp \ + LayerCache.cpp \ + LayerRenderer.cpp \ + Matrix.cpp \ + OpenGLRenderer.cpp \ + Patch.cpp \ + PatchCache.cpp \ + PathCache.cpp \ + PathTessellator.cpp \ + PixelBuffer.cpp \ + Program.cpp \ + ProgramCache.cpp \ + RenderBufferCache.cpp \ + RenderNode.cpp \ + RenderProperties.cpp \ + RenderState.cpp \ + ResourceCache.cpp \ + ShadowTessellator.cpp \ + SkiaShader.cpp \ + Snapshot.cpp \ + SpotShadow.cpp \ + Stencil.cpp \ + TessellationCache.cpp \ + Texture.cpp \ + TextureCache.cpp \ + TextDropShadowCache.cpp + +# RenderThread stuff +LOCAL_SRC_FILES += \ + renderthread/CanvasContext.cpp \ + renderthread/DrawFrameTask.cpp \ + renderthread/EglManager.cpp \ + renderthread/RenderProxy.cpp \ + renderthread/RenderTask.cpp \ + renderthread/RenderThread.cpp \ + renderthread/TimeLord.cpp + +intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) + +LOCAL_C_INCLUDES += \ + external/skia/src/core + +LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES +LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui libgui + +ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT)) + LOCAL_CFLAGS += -DANDROID_ENABLE_RENDERSCRIPT + LOCAL_SHARED_LIBRARIES += libRS libRScpp + LOCAL_C_INCLUDES += \ + $(intermediates) \ + frameworks/rs/cpp \ + frameworks/rs \ + +endif + +ifndef HWUI_COMPILE_SYMBOLS + LOCAL_CFLAGS += -fvisibility=hidden +endif + +ifdef HWUI_COMPILE_FOR_PERF + # TODO: Non-arm? + LOCAL_CFLAGS += -fno-omit-frame-pointer -marm -mapcs +endif + +# Defaults for ATRACE_TAG and LOG_TAG for libhwui +LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" + +LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter -Wunused -Wunreachable-code diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index d0b9d82552fa..aa8db265d847 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -2,118 +2,12 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -# Too many unused parameters in external/skia/include and this directory. -# getConfig in external/skia/include/core/SkBitmap.h is deprecated. -# Allow Gnu extension: in-class initializer of static 'const float' member. -LOCAL_CLANG_CFLAGS += \ - -Wno-gnu-static-float-init +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE := libhwui +LOCAL_MODULE_TAGS := optional -# Only build libhwui when USE_OPENGL_RENDERER is -# defined in the current device/board configuration -ifeq ($(USE_OPENGL_RENDERER),true) - LOCAL_SRC_FILES := \ - utils/Blur.cpp \ - utils/GLUtils.cpp \ - utils/SortedListImpl.cpp \ - thread/TaskManager.cpp \ - font/CacheTexture.cpp \ - font/Font.cpp \ - AmbientShadow.cpp \ - AnimationContext.cpp \ - Animator.cpp \ - AnimatorManager.cpp \ - AssetAtlas.cpp \ - DamageAccumulator.cpp \ - FontRenderer.cpp \ - GammaFontRenderer.cpp \ - Caches.cpp \ - DisplayList.cpp \ - DeferredDisplayList.cpp \ - DeferredLayerUpdater.cpp \ - DisplayListLogBuffer.cpp \ - DisplayListRenderer.cpp \ - Dither.cpp \ - DrawProfiler.cpp \ - Extensions.cpp \ - FboCache.cpp \ - GradientCache.cpp \ - Image.cpp \ - Interpolator.cpp \ - Layer.cpp \ - LayerCache.cpp \ - LayerRenderer.cpp \ - Matrix.cpp \ - OpenGLRenderer.cpp \ - Patch.cpp \ - PatchCache.cpp \ - PathCache.cpp \ - PathTessellator.cpp \ - PixelBuffer.cpp \ - Program.cpp \ - ProgramCache.cpp \ - RenderBufferCache.cpp \ - RenderNode.cpp \ - RenderProperties.cpp \ - RenderState.cpp \ - ResourceCache.cpp \ - ShadowTessellator.cpp \ - SkiaShader.cpp \ - Snapshot.cpp \ - SpotShadow.cpp \ - StatefulBaseRenderer.cpp \ - Stencil.cpp \ - TessellationCache.cpp \ - Texture.cpp \ - TextureCache.cpp \ - TextDropShadowCache.cpp +include $(LOCAL_PATH)/Android.common.mk -# RenderThread stuff - LOCAL_SRC_FILES += \ - renderthread/CanvasContext.cpp \ - renderthread/DrawFrameTask.cpp \ - renderthread/EglManager.cpp \ - renderthread/RenderProxy.cpp \ - renderthread/RenderTask.cpp \ - renderthread/RenderThread.cpp \ - renderthread/TimeLord.cpp +include $(BUILD_SHARED_LIBRARY) - intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) - - LOCAL_C_INCLUDES += \ - external/skia/src/core - - LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES - LOCAL_CFLAGS += -Wno-unused-parameter - LOCAL_MODULE_CLASS := SHARED_LIBRARIES - LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui libgui - LOCAL_MODULE := libhwui - LOCAL_MODULE_TAGS := optional - - ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT)) - LOCAL_CFLAGS += -DANDROID_ENABLE_RENDERSCRIPT - LOCAL_SHARED_LIBRARIES += libRS libRScpp - LOCAL_C_INCLUDES += \ - $(intermediates) \ - frameworks/rs/cpp \ - frameworks/rs \ - - endif - - ifndef HWUI_COMPILE_SYMBOLS - LOCAL_CFLAGS += -fvisibility=hidden - endif - - ifdef HWUI_COMPILE_FOR_PERF - # TODO: Non-arm? - LOCAL_CFLAGS += -fno-omit-frame-pointer -marm -mapcs - endif - - # Defaults for ATRACE_TAG and LOG_TAG for libhwui - LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" - - LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code - - include $(BUILD_SHARED_LIBRARY) - - include $(call all-makefiles-under,$(LOCAL_PATH)) -endif +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 8bf2107b70bb..805f8443c7fb 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -20,6 +20,7 @@ #include <set> #include "AnimationContext.h" +#include "Interpolator.h" #include "RenderNode.h" #include "RenderProperties.h" @@ -35,7 +36,6 @@ BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) , mFinalValue(finalValue) , mDeltaValue(0) , mFromValue(0) - , mInterpolator(0) , mStagingPlayState(NOT_STARTED) , mPlayState(NOT_STARTED) , mHasStartValue(false) @@ -46,7 +46,6 @@ BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) } BaseRenderNodeAnimator::~BaseRenderNodeAnimator() { - delete mInterpolator; } void BaseRenderNodeAnimator::checkMutable() { @@ -57,8 +56,7 @@ void BaseRenderNodeAnimator::checkMutable() { void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) { checkMutable(); - delete mInterpolator; - mInterpolator = interpolator; + mInterpolator.reset(interpolator); } void BaseRenderNodeAnimator::setStartValue(float value) { @@ -118,7 +116,7 @@ void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) { } // No interpolator was set, use the default if (!mInterpolator) { - mInterpolator = Interpolator::createDefaultInterpolator(); + mInterpolator.reset(Interpolator::createDefaultInterpolator()); } if (mDuration < 0 || mDuration > 50000) { ALOGW("Your duration is strange and confusing: %" PRId64, mDuration); diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h index 35a4a09c287f..aa3d301bbf07 100644 --- a/libs/hwui/Animator.h +++ b/libs/hwui/Animator.h @@ -16,13 +16,12 @@ #ifndef ANIMATOR_H #define ANIMATOR_H +#include <memory> #include <cutils/compiler.h> #include <utils/RefBase.h> #include <utils/StrongPointer.h> +#include <utils/Timers.h> -#include "CanvasProperty.h" -#include "Interpolator.h" -#include "TreeInfo.h" #include "utils/Macros.h" namespace android { @@ -30,6 +29,9 @@ namespace uirenderer { class AnimationContext; class BaseRenderNodeAnimator; +class CanvasPropertyPrimitive; +class CanvasPropertyPaint; +class Interpolator; class RenderNode; class RenderProperties; @@ -98,7 +100,7 @@ protected: float mDeltaValue; float mFromValue; - Interpolator* mInterpolator; + std::unique_ptr<Interpolator> mInterpolator; PlayState mStagingPlayState; PlayState mPlayState; bool mHasStartValue; diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index c28fb88a0361..9a4ba214308f 100644 --- a/libs/hwui/AnimatorManager.cpp +++ b/libs/hwui/AnimatorManager.cpp @@ -17,7 +17,9 @@ #include <algorithm> +#include "Animator.h" #include "AnimationContext.h" +#include "DamageAccumulator.h" #include "RenderNode.h" namespace android { diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h index d03d4272e34d..fb75eb8599b4 100644 --- a/libs/hwui/AnimatorManager.h +++ b/libs/hwui/AnimatorManager.h @@ -21,7 +21,6 @@ #include <cutils/compiler.h> #include <utils/StrongPointer.h> -#include "TreeInfo.h" #include "utils/Macros.h" namespace android { @@ -30,6 +29,7 @@ namespace uirenderer { class AnimationHandle; class BaseRenderNodeAnimator; class RenderNode; +class TreeInfo; // Responsible for managing the animators for a single RenderNode class AnimatorManager { diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp index 52ca92dcd388..366e486db5d9 100644 --- a/libs/hwui/AssetAtlas.cpp +++ b/libs/hwui/AssetAtlas.cpp @@ -18,6 +18,7 @@ #include "AssetAtlas.h" #include "Caches.h" +#include "Image.h" #include <GLES2/gl2ext.h> diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h index fffd7401e608..1772effb911b 100644 --- a/libs/hwui/AssetAtlas.h +++ b/libs/hwui/AssetAtlas.h @@ -27,7 +27,6 @@ #include <SkBitmap.h> -#include "Image.h" #include "Texture.h" #include "UvMapper.h" @@ -35,6 +34,7 @@ namespace android { namespace uirenderer { class Caches; +class Image; /** * An asset atlas holds a collection of framework bitmaps in a single OpenGL @@ -106,7 +106,7 @@ public: friend class AssetAtlas; }; - AssetAtlas(): mTexture(NULL), mImage(NULL), + AssetAtlas(): mTexture(nullptr), mImage(nullptr), mBlendKey(true), mOpaqueKey(false) { } ~AssetAtlas() { terminate(); } diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 4bbe6edf7296..ebeb845e77f6 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -21,6 +21,7 @@ #include "Caches.h" #include "DisplayListRenderer.h" +#include "GammaFontRenderer.h" #include "Properties.h" #include "LayerRenderer.h" #include "ShadowTessellator.h" @@ -28,10 +29,8 @@ namespace android { -#ifdef USE_OPENGL_RENDERER using namespace uirenderer; ANDROID_SINGLETON_STATIC_INSTANCE(Caches); -#endif namespace uirenderer { @@ -225,9 +224,8 @@ void Caches::terminate() { mCurrentBuffer = 0; glDeleteBuffers(1, &mMeshIndices); - delete[] mRegionMesh; mMeshIndices = 0; - mRegionMesh = NULL; + mRegionMesh.release(); glDeleteBuffers(1, &mShadowStripsIndices); mShadowStripsIndices = 0; @@ -407,7 +405,7 @@ bool Caches::bindIndicesBufferInternal(const GLuint buffer) { bool Caches::bindQuadIndicesBuffer() { if (!mMeshIndices) { - uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6]; + std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[gMaxNumberOfQuads * 6]); for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) { uint16_t quad = i * 4; int index = i * 6; @@ -422,9 +420,7 @@ bool Caches::bindQuadIndicesBuffer() { glGenBuffers(1, &mMeshIndices); bool force = bindIndicesBufferInternal(mMeshIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t), - regionIndices, GL_STATIC_DRAW); - - delete[] regionIndices; + regionIndices.get(), GL_STATIC_DRAW); return force; } @@ -433,14 +429,12 @@ bool Caches::bindQuadIndicesBuffer() { bool Caches::bindShadowIndicesBuffer() { if (!mShadowStripsIndices) { - uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT]; - ShadowTessellator::generateShadowIndices(shadowIndices); + std::unique_ptr<uint16_t[]> shadowIndices(new uint16_t[MAX_SHADOW_INDEX_COUNT]); + ShadowTessellator::generateShadowIndices(shadowIndices.get()); glGenBuffers(1, &mShadowStripsIndices); bool force = bindIndicesBufferInternal(mShadowStripsIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), - shadowIndices, GL_STATIC_DRAW); - - delete[] shadowIndices; + shadowIndices.get(), GL_STATIC_DRAW); return force; } @@ -688,10 +682,10 @@ void Caches::unregisterFunctors(uint32_t functorCount) { TextureVertex* Caches::getRegionMesh() { // Create the mesh, 2 triangles and 4 vertices per rectangle in the region if (!mRegionMesh) { - mRegionMesh = new TextureVertex[gMaxNumberOfQuads * 4]; + mRegionMesh.reset(new TextureVertex[gMaxNumberOfQuads * 4]); } - return mRegionMesh; + return mRegionMesh.get(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 2e179af8eecc..b0eebd715179 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -31,13 +31,13 @@ #include <cutils/compiler.h> +#include <SkPath.h> + #include "thread/TaskProcessor.h" #include "thread/TaskManager.h" #include "AssetAtlas.h" #include "Extensions.h" -#include "FontRenderer.h" -#include "GammaFontRenderer.h" #include "TextureCache.h" #include "LayerCache.h" #include "RenderBufferCache.h" @@ -55,6 +55,8 @@ namespace android { namespace uirenderer { +class GammaFontRenderer; + /////////////////////////////////////////////////////////////////////////////// // Globals /////////////////////////////////////////////////////////////////////////////// @@ -414,7 +416,7 @@ private: Extensions& mExtensions; // Used to render layers - TextureVertex* mRegionMesh; + std::unique_ptr<TextureVertex[]> mRegionMesh; // Global index buffer GLuint mMeshIndices; diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/CanvasState.cpp index 88d6f6802909..20cc17e9b5f2 100644 --- a/libs/hwui/StatefulBaseRenderer.cpp +++ b/libs/hwui/CanvasState.cpp @@ -14,41 +14,45 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <SkCanvas.h> -#include "StatefulBaseRenderer.h" - +#include "CanvasState.h" #include "utils/MathUtils.h" namespace android { namespace uirenderer { -StatefulBaseRenderer::StatefulBaseRenderer() + +CanvasState::CanvasState(CanvasStateClient& renderer) : mDirtyClip(false) , mWidth(-1) , mHeight(-1) , mSaveCount(1) , mFirstSnapshot(new Snapshot) + , mCanvas(renderer) , mSnapshot(mFirstSnapshot) { + } -void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, +CanvasState::~CanvasState() { + +} + +void CanvasState::initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, const Vector3& lightCenter) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); - mSnapshot->fbo = getTargetFbo(); + mSnapshot->fbo = mCanvas.onGetTargetFbo(); mSnapshot->setRelativeLightCenter(lightCenter); mSaveCount = 1; } -void StatefulBaseRenderer::setViewport(int width, int height) { +void CanvasState::setViewport(int width, int height) { mWidth = width; mHeight = height; mFirstSnapshot->initializeViewport(width, height); - onViewportInitialized(); + mCanvas.onViewportInitialized(); // create a temporary 1st snapshot, so old snapshots are released, // and viewport can be queried safely. @@ -63,24 +67,24 @@ void StatefulBaseRenderer::setViewport(int width, int height) { /////////////////////////////////////////////////////////////////////////////// /** - * Non-virtual implementation of save, guaranteed to save without side-effects + * Guaranteed to save without side-effects * - * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save + * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save * stack, and ensures restoreToCount() doesn't call back into subclass overrides. */ -int StatefulBaseRenderer::saveSnapshot(int flags) { +int CanvasState::saveSnapshot(int flags) { mSnapshot = new Snapshot(mSnapshot, flags); return mSaveCount++; } -int StatefulBaseRenderer::save(int flags) { +int CanvasState::save(int flags) { return saveSnapshot(flags); } /** - * Non-virtual implementation of restore, guaranteed to restore without side-effects. + * Guaranteed to restore without side-effects. */ -void StatefulBaseRenderer::restoreSnapshot() { +void CanvasState::restoreSnapshot() { sp<Snapshot> toRemove = mSnapshot; sp<Snapshot> toRestore = mSnapshot->previous; @@ -88,16 +92,16 @@ void StatefulBaseRenderer::restoreSnapshot() { mSnapshot = toRestore; // subclass handles restore implementation - onSnapshotRestored(*toRemove, *toRestore); + mCanvas.onSnapshotRestored(*toRemove, *toRestore); } -void StatefulBaseRenderer::restore() { +void CanvasState::restore() { if (mSaveCount > 1) { restoreSnapshot(); } } -void StatefulBaseRenderer::restoreToCount(int saveCount) { +void CanvasState::restoreToCount(int saveCount) { if (saveCount < 1) saveCount = 1; while (mSaveCount > saveCount) { @@ -109,40 +113,40 @@ void StatefulBaseRenderer::restoreToCount(int saveCount) { // Matrix /////////////////////////////////////////////////////////////////////////////// -void StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { +void CanvasState::getMatrix(SkMatrix* matrix) const { mSnapshot->transform->copyTo(*matrix); } -void StatefulBaseRenderer::translate(float dx, float dy, float dz) { +void CanvasState::translate(float dx, float dy, float dz) { mSnapshot->transform->translate(dx, dy, dz); } -void StatefulBaseRenderer::rotate(float degrees) { +void CanvasState::rotate(float degrees) { mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); } -void StatefulBaseRenderer::scale(float sx, float sy) { +void CanvasState::scale(float sx, float sy) { mSnapshot->transform->scale(sx, sy, 1.0f); } -void StatefulBaseRenderer::skew(float sx, float sy) { +void CanvasState::skew(float sx, float sy) { mSnapshot->transform->skew(sx, sy); } -void StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) { +void CanvasState::setMatrix(const SkMatrix& matrix) { mSnapshot->transform->load(matrix); } -void StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { +void CanvasState::setMatrix(const Matrix4& matrix) { mSnapshot->transform->load(matrix); } -void StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) { +void CanvasState::concatMatrix(const SkMatrix& matrix) { mat4 transform(matrix); mSnapshot->transform->multiply(transform); } -void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { +void CanvasState::concatMatrix(const Matrix4& matrix) { mSnapshot->transform->multiply(matrix); } @@ -150,7 +154,7 @@ void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { // Clip /////////////////////////////////////////////////////////////////////////////// -bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { +bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { if (CC_LIKELY(currentTransform()->rectToRect())) { mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); return !mSnapshot->clipRect->isEmpty(); @@ -159,10 +163,10 @@ bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bo SkPath path; path.addRect(left, top, right, bottom); - return StatefulBaseRenderer::clipPath(&path, op); + return CanvasState::clipPath(&path, op); } -bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { +bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { SkMatrix transform; currentTransform()->copyTo(transform); @@ -189,12 +193,12 @@ bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { return !mSnapshot->clipRect->isEmpty(); } -bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { +bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); return !mSnapshot->clipRect->isEmpty(); } -void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { +void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { Rect bounds; float radius; if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported @@ -209,7 +213,7 @@ void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const } } -void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, +void CanvasState::setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius, bool highPriority) { mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); } @@ -229,7 +233,7 @@ void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, * @param snapOut if set, the geometry will be treated as having an AA ramp. * See Rect::snapGeometryToPixelBoundaries() */ -bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, +bool CanvasState::calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const { @@ -259,18 +263,7 @@ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, return false; } -/** - * Returns false if drawing won't be clipped out. - * - * Makes the decision conservatively, by rounding out the mapped rect before comparing with the - * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but - * rejection is still desired. - * - * This function, unlike quickRejectSetupScissor, should be used where precise geometry information - * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass - * rejection where precise rejection isn't important, or precise information isn't available. - */ -bool StatefulBaseRenderer::quickRejectConservative(float left, float top, +bool CanvasState::quickRejectConservative(float left, float top, float right, float bottom) const { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; @@ -288,5 +281,5 @@ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, return false; } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h new file mode 100644 index 000000000000..9e6a9c3cf63b --- /dev/null +++ b/libs/hwui/CanvasState.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2014 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. + */ + +#ifndef ANDROID_HWUI_CANVAS_STATE_H +#define ANDROID_HWUI_CANVAS_STATE_H + +#include <SkMatrix.h> +#include <SkPath.h> +#include <SkRegion.h> + +#include "Snapshot.h" + +namespace android { +namespace uirenderer { + +/** + * Abstract base class for any class containing CanvasState. + * Defines three mandatory callbacks. + */ +class CanvasStateClient { +public: + CanvasStateClient() { } + virtual ~CanvasStateClient() { } + + /** + * Callback allowing embedder to take actions in the middle of a + * setViewport() call. + */ + virtual void onViewportInitialized() = 0; + + /** + * Callback allowing embedder to take actions in the middle of a + * restore() call. May be called several times sequentially. + */ + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; + + /** + * Allows subclasses to control what value is stored in snapshot's + * fbo field in * initializeSaveStack. + */ + virtual GLuint onGetTargetFbo() const = 0; + +}; // class CanvasStateClient + +/** + * Implements Canvas state methods on behalf of Renderers. + * + * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the + * Renderer interface. Drawing and recording classes that include a CanvasState will have + * different use cases: + * + * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into + * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. + * + * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations + * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so + * that quickRejection can also be used. + */ + +class ANDROID_API CanvasState { +public: + CanvasState(CanvasStateClient& renderer); + ~CanvasState(); + + /** + * Initializes the first snapshot, computing the projection matrix, + * and stores the dimensions of the render target. + */ + void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, + const Vector3& lightCenter); + + void setViewport(int width, int height); + + bool hasRectToRectTransform() const { + return CC_LIKELY(currentTransform()->rectToRect()); + } + + // Save (layer) + int getSaveCount() const { return mSaveCount; } + int save(int flags); + void restore(); + void restoreToCount(int saveCount); + + // Save/Restore without side-effects + int saveSnapshot(int flags); + void restoreSnapshot(); + + // Matrix + void getMatrix(SkMatrix* outMatrix) const; + void translate(float dx, float dy, float dz = 0.0f); + void rotate(float degrees); + void scale(float sx, float sy); + void skew(float sx, float sy); + + void setMatrix(const SkMatrix& matrix); + void setMatrix(const Matrix4& matrix); // internal only convenience method + void concatMatrix(const SkMatrix& matrix); + void concatMatrix(const Matrix4& matrix); // internal only convenience method + + // Clip + const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } + const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } + + bool quickRejectConservative(float left, float top, float right, float bottom) const; + + bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); + bool clipPath(const SkPath* path, SkRegion::Op op); + bool clipRegion(const SkRegion* region, SkRegion::Op op); + + bool isCurrentClipSimple() const { + return currentSnapshot()->clipRegion->isEmpty(); + } + + /** + * Sets a "clipping outline", which is independent from the regular clip. + * Currently only supports rectangles or rounded rectangles; passing in a + * more complicated outline fails silently. Replaces any previous clipping + * outline. + */ + void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority = true); + + /** + * Returns true if drawing in the rectangle (left, top, right, bottom) + * will be clipped out. Is conservative: might return false when subpixel- + * perfect tests would return true. + */ + bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, + bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; + + void setDirtyClip(bool opaque) { mDirtyClip = opaque; } + bool getDirtyClip() const { return mDirtyClip; } + + void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } + void setEmpty(bool value) { mSnapshot->empty = value; } + void setInvisible(bool value) { mSnapshot->invisible = value; } + + inline const mat4* currentTransform() const { return currentSnapshot()->transform; } + inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; } + inline Region* currentRegion() const { return currentSnapshot()->region; } + inline int currentFlags() const { return currentSnapshot()->flags; } + const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } + inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } + int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } + int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } + int getWidth() { return mWidth; } + int getHeight() { return mHeight; } + + inline const Snapshot* currentSnapshot() const { + return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get(); + } + inline Snapshot* writableSnapshot() { return mSnapshot.get(); } + inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } + +private: + /// No default constructor - must supply a CanvasStateClient (mCanvas). + CanvasState(); + + /// indicates that the clip has been changed since the last time it was consumed + bool mDirtyClip; + + /// Dimensions of the drawing surface + int mWidth, mHeight; + + /// Number of saved states + int mSaveCount; + + /// Base state + sp<Snapshot> mFirstSnapshot; + + /// Host providing callbacks + CanvasStateClient& mCanvas; + + /// Current state + sp<Snapshot> mSnapshot; + +}; // class CanvasState + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_CANVAS_STATE_H diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index 6fd0151fc377..7355baaebbe6 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -52,7 +52,7 @@ namespace uirenderer { class Batch { public: - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0; + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0; virtual ~Batch() {} virtual bool purelyDrawBatch() { return false; } virtual bool coversBounds(const Rect& bounds) { return false; } @@ -91,11 +91,10 @@ public: return false; } - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("%d replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)", index, this, mOps.size(), getBatchId(), getMergeId()); - status_t status = DrawGlInfo::kStatusDone; DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); for (unsigned int i = 0; i < mOps.size(); i++) { DrawOp* op = mOps[i].op; @@ -106,7 +105,7 @@ public: renderer.eventMark(op->name()); #endif logBuffer.writeCommand(0, op->name()); - status |= op->applyDraw(renderer, dirty); + op->applyDraw(renderer, dirty); #if DEBUG_MERGE_BEHAVIOR const Rect& bounds = state->mBounds; @@ -118,7 +117,6 @@ public: batchColor); #endif } - return status; } virtual bool purelyDrawBatch() { return true; } @@ -235,26 +233,6 @@ public: return false; } - /* Draw Modifiers compatibility check - * - * Shadows are ignored, as only text uses them, and in that case they are drawn - * per-DrawTextOp, before the unified text draw. Because of this, it's always safe to merge - * text UNLESS a later draw's shadow should overlays a previous draw's text. This is covered - * above with the intersection check. - * - * OverrideLayerAlpha is also ignored, as it's only used for drawing layers, which are never - * merged. - * - * These ignore cases prevent us from simply memcmp'ing the drawModifiers - */ - const DrawModifiers& lhsMod = lhs->mDrawModifiers; - const DrawModifiers& rhsMod = rhs->mDrawModifiers; - - // Draw filter testing expects bit fields to be clear if filter not set. - if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false; - if (lhsMod.mPaintFilterClearBits != rhsMod.mPaintFilterClearBits) return false; - if (lhsMod.mPaintFilterSetBits != rhsMod.mPaintFilterSetBits) return false; - return true; } @@ -269,12 +247,13 @@ public: if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom; } - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("%d replaying MergingDrawBatch %p, with %d ops," " clip flags %x (batch id %x, merge id %p)", index, this, mOps.size(), mClipSideFlags, getBatchId(), getMergeId()); if (mOps.size() == 1) { - return DrawBatch::replay(renderer, dirty, -1); + DrawBatch::replay(renderer, dirty, -1); + return; } // clipping in the merged case is done ahead of time since all ops share the clip (if any) @@ -289,13 +268,12 @@ public: renderer.eventMark("multiDraw"); renderer.eventMark(op->name()); #endif - status_t status = op->multiDraw(renderer, dirty, mOps, mBounds); + op->multiDraw(renderer, dirty, mOps, mBounds); #if DEBUG_MERGE_BEHAVIOR renderer.drawScreenSpaceColorRect(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom, DEBUG_COLOR_MERGEDBATCH); #endif - return status; } private: @@ -313,7 +291,7 @@ public: // creates a single operation batch StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {} - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("replaying state op batch %p", this); renderer.restoreDisplayState(*mState); @@ -322,7 +300,6 @@ public: // renderer.restoreToCount directly int saveCount = -1; mOp->applyState(renderer, saveCount); - return DrawGlInfo::kStatusDone; } private: @@ -332,15 +309,14 @@ private: class RestoreToCountBatch : public Batch { public: - RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, - int restoreCount) : mState(state), mRestoreCount(restoreCount) {} + RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) : + mState(state), mRestoreCount(restoreCount) {} - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount); renderer.restoreDisplayState(*mState); renderer.restoreToCount(mRestoreCount); - return DrawGlInfo::kStatusDone; } private: @@ -358,9 +334,8 @@ private: #if DEBUG_MERGE_BEHAVIOR class BarrierDebugBatch : public Batch { - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { renderer.drawScreenSpaceColorRect(0, 0, 10000, 10000, DEBUG_COLOR_BARRIER); - return DrawGlInfo::kStatusDrew; } }; #endif @@ -647,26 +622,22 @@ void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, S // Replay / flush ///////////////////////////////////////////////////////////////////////////////// -static status_t replayBatchList(const Vector<Batch*>& batchList, +static void replayBatchList(const Vector<Batch*>& batchList, OpenGLRenderer& renderer, Rect& dirty) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < batchList.size(); i++) { if (batchList[i]) { - status |= batchList[i]->replay(renderer, dirty, i); + batchList[i]->replay(renderer, dirty, i); } } DEFER_LOGD("--flushed, drew %d batches", batchList.size()); - return status; } -status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { +void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { ATRACE_NAME("flush drawing commands"); Caches::getInstance().fontRenderer->endPrecaching(); - status_t status = DrawGlInfo::kStatusDone; - - if (isEmpty()) return status; // nothing to flush + if (isEmpty()) return; // nothing to flush renderer.restoreToCount(1); DEFER_LOGD("--flushing"); @@ -685,14 +656,13 @@ status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { } // NOTE: depth of the save stack at this point, before playback, should be reflected in // FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly - status |= replayBatchList(mBatches, renderer, dirty); + replayBatchList(mBatches, renderer, dirty); renderer.restoreToCount(1); renderer.setDrawModifiers(restoreDrawModifiers); DEFER_LOGD("--flush complete, returning %x", status); clear(); - return status; } void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) { diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index f7f30b101bc2..c92ab91d21bf 100644 --- a/libs/hwui/DeferredDisplayList.h +++ b/libs/hwui/DeferredDisplayList.h @@ -69,7 +69,7 @@ public: class OpStatePair { public: OpStatePair() - : op(NULL), state(NULL) {} + : op(nullptr), state(nullptr) {} OpStatePair(DrawOp* newOp, const DeferredDisplayState* newState) : op(newOp), state(newState) {} OpStatePair(const OpStatePair& other) @@ -106,7 +106,7 @@ public: * Plays back all of the draw ops recorded into batches to the renderer. * Adjusts the state of the renderer as necessary, and restores it when complete */ - status_t flush(OpenGLRenderer& renderer, Rect& dirty); + void flush(OpenGLRenderer& renderer, Rect& dirty); void addClip(OpenGLRenderer& renderer, ClipOp* op); void addSaveLayer(OpenGLRenderer& renderer, SaveLayerOp* op, int newSaveCount); diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index d02455c8fc1d..16d61fd37824 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -97,8 +97,8 @@ void DeferredLayerUpdater::doUpdateTexImage() { sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); if (buffer != NULL) { // force filtration if buffer size != layer size - forceFilter = mWidth != buffer->getWidth() - || mHeight != buffer->getHeight(); + forceFilter = mWidth != static_cast<int>(buffer->getWidth()) + || mHeight != static_cast<int>(buffer->getHeight()); } #if DEBUG_RENDERER diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 84411edbebfc..61efafe46e61 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -24,7 +24,6 @@ #include "Layer.h" #include "Rect.h" -#include "RenderNode.h" #include "renderthread/RenderThread.h" namespace android { @@ -39,7 +38,7 @@ public: ANDROID_API DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer); ANDROID_API ~DeferredLayerUpdater(); - ANDROID_API bool setSize(uint32_t width, uint32_t height) { + ANDROID_API bool setSize(int width, int height) { if (mWidth != width || mHeight != height) { mWidth = width; mHeight = height; @@ -84,8 +83,8 @@ public: private: // Generic properties - uint32_t mWidth; - uint32_t mHeight; + int mWidth; + int mHeight; bool mBlend; SkColorFilter* mColorFilter; int mAlpha; diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 895316696ef7..249ada0d1fe5 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -62,18 +62,6 @@ void DisplayListData::cleanupResources() { resourceCache.unlock(); - for (size_t i = 0; i < paints.size(); i++) { - delete paints.itemAt(i); - } - - for (size_t i = 0; i < regions.size(); i++) { - delete regions.itemAt(i); - } - - for (size_t i = 0; i < paths.size(); i++) { - delete paths.itemAt(i); - } - bitmapResources.clear(); ownedBitmapResources.clear(); patchResources.clear(); diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index a9a9148f9e25..cfd60ad37a90 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -38,8 +38,9 @@ #include <androidfw/ResourceTypes.h> #include "Debug.h" -#include "Matrix.h" +#include "CanvasProperty.h" #include "DeferredDisplayList.h" +#include "Matrix.h" #include "RenderProperties.h" class SkBitmap; @@ -66,7 +67,7 @@ class DrawRenderNodeOp; /** * Holds data used in the playback a tree of DisplayLists. */ -class PlaybackStateStruct { +struct PlaybackStateStruct { protected: PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) : mRenderer(renderer) @@ -95,14 +96,12 @@ struct DeferStateStruct : public PlaybackStateStruct { DeferredDisplayList& mDeferredList; }; -class ReplayStateStruct : public PlaybackStateStruct { -public: +struct ReplayStateStruct : public PlaybackStateStruct { ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator), - mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {} + mDirty(dirty) {} Rect& mDirty; - status_t mDrawGlStatus; LinearAllocator mReplayAllocator; }; @@ -138,10 +137,10 @@ public: Vector<const SkBitmap*> ownedBitmapResources; Vector<const Res_png_9patch*> patchResources; - Vector<const SkPaint*> paints; - Vector<const SkPath*> paths; + std::vector<std::unique_ptr<const SkPaint>> paints; + std::vector<std::unique_ptr<const SkRegion>> regions; + std::vector<std::unique_ptr<const SkPath>> paths; SortedVector<const SkPath*> sourcePaths; - Vector<const SkRegion*> regions; Vector<Functor*> functors; const Vector<Chunk>& getChunks() const { diff --git a/libs/hwui/DisplayListLogBuffer.cpp b/libs/hwui/DisplayListLogBuffer.cpp index bc9e7bd70609..23b6cff8dd02 100644 --- a/libs/hwui/DisplayListLogBuffer.cpp +++ b/libs/hwui/DisplayListLogBuffer.cpp @@ -47,10 +47,8 @@ namespace android { -#ifdef USE_OPENGL_RENDERER using namespace uirenderer; ANDROID_SINGLETON_STATIC_INSTANCE(DisplayListLogBuffer); -#endif namespace uirenderer { diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 8a5e21d3f456..e42a9e424d2a 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -17,10 +17,6 @@ #ifndef ANDROID_HWUI_DISPLAY_OPERATION_H #define ANDROID_HWUI_DISPLAY_OPERATION_H -#ifndef LOG_TAG - #define LOG_TAG "OpenGLRenderer" -#endif - #include <SkColor.h> #include <SkPath.h> #include <SkPathOps.h> @@ -32,15 +28,13 @@ #include "AssetAtlas.h" #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" +#include "GammaFontRenderer.h" +#include "Patch.h" +#include "RenderNode.h" #include "RenderState.h" #include "UvMapper.h" #include "utils/LinearAllocator.h" -#define CRASH() do { \ - *(int *)(uintptr_t) 0xbbadbeef = 0; \ - ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ -} while(false) - // Use OP_LOG for logging with arglist, OP_LOGS if just printing char* #define OP_LOGS(s) OP_LOG("%s", (s)) #define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ ) @@ -63,9 +57,9 @@ class DisplayListOp { public: // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted. // standard new() intentionally not implemented, and delete/deconstructor should never be used. - virtual ~DisplayListOp() { CRASH(); } - static void operator delete(void* ptr) { CRASH(); } - /** static void* operator new(size_t size); PURPOSELY OMITTED **/ + virtual ~DisplayListOp() { LOG_ALWAYS_FATAL("Destructor not supported"); } + static void operator delete(void* ptr) { LOG_ALWAYS_FATAL("delete not supported"); } + static void* operator new(size_t size) = delete; /** PURPOSELY OMITTED **/ static void* operator new(size_t size, LinearAllocator& allocator) { return allocator.alloc(size); } @@ -90,10 +84,6 @@ public: class StateOp : public DisplayListOp { public: - StateOp() {}; - - virtual ~StateOp() {} - virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { // default behavior only affects immediate, deferrable state, issue directly to renderer @@ -133,10 +123,10 @@ public: return; } - replayStruct.mDrawGlStatus |= applyDraw(replayStruct.mRenderer, replayStruct.mDirty); + applyDraw(replayStruct.mRenderer, replayStruct.mDirty); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0; + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0; /** * Draw multiple instances of an operation, must be overidden for operations that merge @@ -145,14 +135,12 @@ public: * and pure translation transformations. Other guarantees of similarity should be enforced by * reducing which operations are tagged as mergeable. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < ops.size(); i++) { renderer.restoreDisplayState(*(ops[i].state), true); - status |= ops[i].op->applyDraw(renderer, dirty); + ops[i].op->applyDraw(renderer, dirty); } - return status; } /** @@ -199,10 +187,6 @@ public: } protected: - const SkPaint* getPaint(OpenGLRenderer& renderer) { - return renderer.filterPaint(mPaint); - } - // Helper method for determining op opaqueness. Assumes op fills its bounds in local // coordinates, and that paint's alpha is used inline bool isOpaqueOverBounds(const DeferredDisplayState& state) { @@ -232,7 +216,7 @@ protected: } - const SkPaint* mPaint; // should be accessed via getPaint() when applying + const SkPaint* mPaint; bool mQuickRejected; }; @@ -606,39 +590,6 @@ private: const SkRegion* mRegion; }; -class ResetPaintFilterOp : public StateOp { -public: - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.resetPaintFilter(); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOGS("ResetPaintFilter"); - } - - virtual const char* name() { return "ResetPaintFilter"; } -}; - -class SetupPaintFilterOp : public StateOp { -public: - SetupPaintFilterOp(int clearBits, int setBits) - : mClearBits(clearBits), mSetBits(setBits) {} - - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.setupPaintFilter(mClearBits, mSetBits); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); - } - - virtual const char* name() { return "SetupPaintFilter"; } - -private: - int mClearBits; - int mSetBits; -}; - /////////////////////////////////////////////////////////////////////////////// // DRAW OPERATIONS - these are operations that can draw to the canvas's device /////////////////////////////////////////////////////////////////////////////// @@ -651,8 +602,8 @@ public: , mEntryValid(false), mEntry(NULL) { } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmap(mBitmap, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmap(mBitmap, mPaint); } AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) { @@ -672,7 +623,7 @@ public: * for each bitmap in the batch. This method is also responsible for dirtying * the current layer, if any. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -709,7 +660,7 @@ public: } } - return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], + renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], pureTranslate, bounds, mPaint); } @@ -757,10 +708,10 @@ public: : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - getPaint(renderer)); + mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -785,8 +736,8 @@ public: DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint) : DrawBitmapOp(bitmap, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmapData(mBitmap, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmapData(mBitmap, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -809,9 +760,9 @@ public: mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), mVertices(vertices), mColors(colors) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, - mVertices, mColors, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, + mVertices, mColors, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -865,7 +816,7 @@ public: * and transforming the vertices of each 9-patch in the batch. This method * is also responsible for dirtying the current layer, if any. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -905,7 +856,7 @@ public: patchOp->mLocalBounds.top + 0.5f); // Copy & transform all the vertices for the current operation - TextureVertex* opVertices = opMesh->vertices; + TextureVertex* opVertices = opMesh->vertices.get(); for (uint32_t j = 0; j < vertexCount; j++, opVertices++) { TextureVertex::set(vertex++, opVertices->x + tx, opVertices->y + ty, @@ -935,16 +886,16 @@ public: indexCount += opMesh->indexCount; } - return renderer.drawPatches(mBitmap, getAtlasEntry(renderer), - &vertices[0], indexCount, getPaint(renderer)); + renderer.drawPatches(mBitmap, getAtlasEntry(renderer), + &vertices[0], indexCount, mPaint); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { // We're not calling the public variant of drawPatch() here // This method won't perform the quickReject() since we've already done it at this point - return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer), + renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer), mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - getPaint(renderer)); + mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -979,8 +930,8 @@ public: DrawColorOp(int color, SkXfermode::Mode mode) : DrawOp(NULL), mColor(color), mMode(mode) {}; - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawColor(mColor, mMode); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawColor(mColor, mMode); } virtual void output(int level, uint32_t logFlags) const { @@ -1026,9 +977,9 @@ public: DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1051,8 +1002,8 @@ public: : DrawBoundedOp(rects, count, paint), mRects(rects), mCount(count) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRects(mRects, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRects(mRects, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1077,9 +1028,9 @@ public: float rx, float ry, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1109,9 +1060,9 @@ public: : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom), mRx(rx), mRy(ry) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, - *mRx, *mRy, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, + *mRx, *mRy, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1136,8 +1087,8 @@ public: : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), mX(x), mY(y), mRadius(radius) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawCircle(mX, mY, mRadius, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1157,8 +1108,8 @@ public: DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint) : DrawOp(paint), mX(x), mY(y), mRadius(radius) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawCircle(*mX, *mY, *mRadius, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawCircle(*mX, *mY, *mRadius, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1178,9 +1129,9 @@ public: DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawOval(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1197,10 +1148,10 @@ public: : DrawStrokableOp(left, top, right, bottom, paint), mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawArc(mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); + mStartAngle, mSweepAngle, mUseCenter, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1228,14 +1179,13 @@ public: mLocalBounds.set(left, top, left + width, top + height); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPath(mPath, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPath(mPath, mPaint); } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - renderer.getCaches().pathCache.precache(mPath, paint); + renderer.getCaches().pathCache.precache(mPath, mPaint); deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; } @@ -1258,8 +1208,8 @@ public: mLocalBounds.outset(strokeWidthOutset()); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawLines(mPoints, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawLines(mPoints, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1285,8 +1235,8 @@ public: DrawPointsOp(const float* points, int count, const SkPaint* paint) : DrawLinesOp(points, count, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPoints(mPoints, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPoints(mPoints, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1311,9 +1261,8 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); - fontRenderer.precache(paint, mText, mCount, SkMatrix::I()); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint); + fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I()); deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? DeferredDisplayList::kOpBatch_Text : @@ -1335,9 +1284,9 @@ public: /* TODO: inherit from DrawBounded and init mLocalBounds */ } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, - mHOffset, mVOffset, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, + mHOffset, mVOffset, mPaint); } virtual const char* name() { return "DrawTextOnPath"; } @@ -1356,8 +1305,8 @@ public: /* TODO: inherit from DrawBounded and init mLocalBounds */ } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint); } virtual const char* name() { return "DrawPosText"; } @@ -1377,12 +1326,11 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint); SkMatrix transform; renderer.findBestFontTransform(state.mMatrix, &transform); if (mPrecacheTransform != transform) { - fontRenderer.precache(paint, mText, mCount, transform); + fontRenderer.precache(mPaint, mText, mCount, transform); mPrecacheTransform = transform; } deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? @@ -1400,16 +1348,15 @@ public: && OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { Rect bounds; getLocalBounds(bounds); - return renderer.drawText(mText, mBytesCount, mCount, mX, mY, - mPositions, getPaint(renderer), mTotalAdvance, bounds); + renderer.drawText(mText, mBytesCount, mCount, mX, mY, + mPositions, mPaint, mTotalAdvance, bounds); } - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < ops.size(); i++) { const DeferredDisplayState& state = *(ops[i].state); DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer; @@ -1418,11 +1365,10 @@ public: DrawTextOp& op = *((DrawTextOp*)ops[i].op); // quickReject() will not occure in drawText() so we can use mLocalBounds // directly, we do not need to account for shadow by calling getLocalBounds() - status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, - op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds, + renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, + op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds, drawOpMode); } - return status; } virtual void output(int level, uint32_t logFlags) const { @@ -1451,11 +1397,10 @@ public: DrawFunctorOp(Functor* functor) : DrawOp(NULL), mFunctor(functor) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { renderer.startMark("GL functor"); - status_t ret = renderer.callDrawGLFunction(mFunctor, dirty); + renderer.callDrawGLFunction(mFunctor, dirty); renderer.endMark(); - return ret; } virtual void output(int level, uint32_t logFlags) const { @@ -1490,9 +1435,8 @@ public: } } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { LOG_ALWAYS_FATAL("should not be called, because replay() is overridden"); - return 0; } virtual void output(int level, uint32_t logFlags) const { @@ -1551,7 +1495,7 @@ public: &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius()); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { TessellationCache::vertexBuffer_pair_t buffers; Matrix4 drawTransform(*(renderer.currentTransform())); renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform, @@ -1559,7 +1503,7 @@ public: &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(), buffers); - return renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second); + renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second); } virtual void output(int level, uint32_t logFlags) const { @@ -1582,8 +1526,8 @@ public: DrawLayerOp(Layer* layer, float x, float y) : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawLayer(mLayer, mX, mY); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawLayer(mLayer, mX, mY); } virtual void output(int level, uint32_t logFlags) const { diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 42ac07efc936..1eefa89aefd9 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -33,10 +33,12 @@ namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer() - : mResourceCache(ResourceCache::getInstance()) + : mState(*this) + , mResourceCache(ResourceCache::getInstance()) , mDisplayListData(NULL) , mTranslateX(0.0f) , mTranslateY(0.0f) + , mHasDeferredTranslate(false) , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) , mRestoreSaveCount(-1) { @@ -60,25 +62,24 @@ DisplayListData* DisplayListRenderer::finishRecording() { return data; } -status_t DisplayListRenderer::prepareDirty(float left, float top, +void DisplayListRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { LOG_ALWAYS_FATAL_IF(mDisplayListData, "prepareDirty called a second time during a recording!"); mDisplayListData = new DisplayListData(); - initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3()); + mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; - mDirtyClip = opaque; + mState.setDirtyClip(opaque); mRestoreSaveCount = -1; - - return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } -void DisplayListRenderer::finish() { +bool DisplayListRenderer::finish() { flushRestoreToCount(); flushTranslate(); + return false; } void DisplayListRenderer::interrupt() { @@ -87,16 +88,15 @@ void DisplayListRenderer::interrupt() { void DisplayListRenderer::resume() { } -status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { +void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay addDrawOp(new (alloc()) DrawFunctorOp(functor)); mDisplayListData->functors.add(functor); - return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } int DisplayListRenderer::save(int flags) { addStateOp(new (alloc()) SaveOp(flags)); - return StatefulBaseRenderer::save(flags); + return mState.save(flags); } void DisplayListRenderer::restore() { @@ -107,13 +107,13 @@ void DisplayListRenderer::restore() { mRestoreSaveCount--; flushTranslate(); - StatefulBaseRenderer::restore(); + mState.restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; flushTranslate(); - StatefulBaseRenderer::restoreToCount(saveCount); + mState.restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, @@ -123,7 +123,7 @@ int DisplayListRenderer::saveLayer(float left, float top, float right, float bot paint = refPaint(paint); addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); - return StatefulBaseRenderer::save(flags); + return mState.save(flags); } void DisplayListRenderer::translate(float dx, float dy, float dz) { @@ -132,81 +132,76 @@ void DisplayListRenderer::translate(float dx, float dy, float dz) { mTranslateX += dx; mTranslateY += dy; flushRestoreToCount(); - StatefulBaseRenderer::translate(dx, dy, dz); + mState.translate(dx, dy, dz); } void DisplayListRenderer::rotate(float degrees) { addStateOp(new (alloc()) RotateOp(degrees)); - StatefulBaseRenderer::rotate(degrees); + mState.rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { addStateOp(new (alloc()) ScaleOp(sx, sy)); - StatefulBaseRenderer::scale(sx, sy); + mState.scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { addStateOp(new (alloc()) SkewOp(sx, sy)); - StatefulBaseRenderer::skew(sx, sy); + mState.skew(sx, sy); } void DisplayListRenderer::setMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) SetMatrixOp(matrix)); - StatefulBaseRenderer::setMatrix(matrix); + mState.setMatrix(matrix); } void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); - StatefulBaseRenderer::concatMatrix(matrix); + mState.concatMatrix(matrix); } bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); - return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); + return mState.clipRect(left, top, right, bottom, op); } bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { path = refPath(path); addStateOp(new (alloc()) ClipPathOp(path, op)); - return StatefulBaseRenderer::clipPath(path, op); + return mState.clipPath(path, op); } bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { region = refRegion(region); addStateOp(new (alloc()) ClipRegionOp(region, op)); - return StatefulBaseRenderer::clipRegion(region, op); + return mState.clipRegion(region, op); } -status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, - int32_t flags) { +void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode"); // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list - DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform()); + DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform()); addRenderNodeOp(op); - - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { +void DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { // We ref the DeferredLayerUpdater due to its thread-safe ref-counting // semantics. mDisplayListData->ref(layerHandle); addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { +void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { bitmap = refBitmap(bitmap); paint = refPaint(paint); addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, +void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (srcLeft == 0 && srcTop == 0 @@ -226,18 +221,16 @@ status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint)); } - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { +void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { bitmap = refBitmapData(bitmap); paint = refPaint(paint); addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { int vertexCount = (meshWidth + 1) * (meshHeight + 1); bitmap = refBitmap(bitmap); @@ -247,39 +240,34 @@ status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWid addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, vertices, colors, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, +void DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { bitmap = refBitmap(bitmap); patch = refPatch(patch); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { +void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { addDrawOp(new (alloc()) DrawColorOp(color, mode)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, +void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, +void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRoundRect( +void DisplayListRenderer::drawRoundRect( CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, @@ -293,16 +281,14 @@ status_t DisplayListRenderer::drawRoundRect( mDisplayListData->ref(paint); addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value, &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { +void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, +void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { mDisplayListData->ref(x); mDisplayListData->ref(y); @@ -310,55 +296,49 @@ status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPrope mDisplayListData->ref(paint); addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, &radius->value, &paint->value)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, +void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, +void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { if (fabs(sweepAngle) >= 360.0f) { - return drawOval(left, top, right, bottom, paint); + drawOval(left, top, right, bottom, paint); + } else { + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, + startAngle, sweepAngle, useCenter, paint)); } - - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, - startAngle, sweepAngle, useCenter, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { +void DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { path = refPath(path); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPathOp(path, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; + if (!text || count <= 0) return; text = refText(text, bytesCount); path = refPath(path); @@ -367,12 +347,11 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, hOffset, vOffset, paint); addDrawOp(op); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; + if (!text || count <= 0) return; text = refText(text, bytesCount); positions = refBuffer<float>(positions, count * 2); @@ -380,7 +359,6 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); addDrawOp(op); - return DrawGlInfo::kStatusDone; } static void simplifyPaint(int color, SkPaint* paint) { @@ -393,11 +371,11 @@ static void simplifyPaint(int color, SkPaint* paint) { paint->setLooper(NULL); } -status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { - if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone; + if (!text || count <= 0 || paintWillNotDrawText(*paint)) return; text = refText(text, bytesCount); positions = refBuffer<float>(positions, count * 2); @@ -429,24 +407,18 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou x, y, positions, paint, totalAdvance, bounds); addDrawOp(op); } - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { - if (count <= 0) return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { + if (count <= 0) return; rects = refBuffer<float>(rects, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); - return DrawGlInfo::kStatusDone; -} - -void DisplayListRenderer::resetPaintFilter() { - addStateOp(new (alloc()) ResetPaintFilterOp()); } -void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { - addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); +void DisplayListRenderer::setDrawFilter(SkDrawFilter* filter) { + mDrawFilter.reset(filter); } void DisplayListRenderer::insertReorderBarrier(bool enableReorder) { diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2cc2be36c74d..34f9c381f154 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -17,13 +17,19 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H +#include <SkDrawFilter.h> #include <SkMatrix.h> #include <SkPaint.h> #include <SkPath.h> +#include <SkRegion.h> +#include <SkTLazy.h> #include <cutils/compiler.h> +#include "CanvasState.h" +#include "DisplayList.h" #include "DisplayListLogBuffer.h" #include "RenderNode.h" +#include "Renderer.h" #include "ResourceCache.h" namespace android { @@ -48,13 +54,15 @@ class DeferredDisplayList; class DeferredLayerUpdater; class DisplayListRenderer; class DisplayListOp; +class DisplayListRenderer; class DrawOp; +class RenderNode; class StateOp; /** * Records drawing commands in a display list for later playback into an OpenGLRenderer. */ -class ANDROID_API DisplayListRenderer: public StatefulBaseRenderer { +class ANDROID_API DisplayListRenderer: public Renderer, public CanvasStateClient { public: DisplayListRenderer(); virtual ~DisplayListRenderer(); @@ -66,102 +74,128 @@ public: // ---------------------------------------------------------------------------- // Frame state operations // ---------------------------------------------------------------------------- - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, + float bottom, bool opaque) override; + virtual void prepare(bool opaque) override { + prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque); + } + virtual bool finish() override; virtual void interrupt(); virtual void resume(); // ---------------------------------------------------------------------------- // Canvas state operations // ---------------------------------------------------------------------------- + virtual void setViewport(int width, int height) override { mState.setViewport(width, height); } + // Save (layer) - virtual int save(int flags); - virtual void restore(); - virtual void restoreToCount(int saveCount); + virtual int getSaveCount() const override { return mState.getSaveCount(); } + virtual int save(int flags) override; + virtual void restore() override; + virtual void restoreToCount(int saveCount) override; virtual int saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags); + const SkPaint* paint, int flags) override; // Matrix - virtual void translate(float dx, float dy, float dz = 0.0f); - virtual void rotate(float degrees); - virtual void scale(float sx, float sy); - virtual void skew(float sx, float sy); + virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } - virtual void setMatrix(const SkMatrix& matrix); - virtual void concatMatrix(const SkMatrix& matrix); + virtual void translate(float dx, float dy, float dz = 0.0f) override; + virtual void rotate(float degrees) override; + virtual void scale(float sx, float sy) override; + virtual void skew(float sx, float sy) override; - // Clip - virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); - virtual bool clipPath(const SkPath* path, SkRegion::Op op); - virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); + virtual void setMatrix(const SkMatrix& matrix) override; + virtual void concatMatrix(const SkMatrix& matrix) override; - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + // Clip + virtual bool clipRect(float left, float top, float right, float bottom, + SkRegion::Op op) override; + virtual bool clipPath(const SkPath* path, SkRegion::Op op) override; + virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override; + + // Misc + virtual void setDrawFilter(SkDrawFilter* filter) override; + virtual const Rect& getLocalClipBounds() const override { return mState.getLocalClipBounds(); } + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } + virtual bool quickRejectConservative(float left, float top, + float right, float bottom) const override { + return mState.quickRejectConservative(left, top, right, bottom); + } bool isCurrentTransformSimple() { - return currentTransform()->isSimple(); + return mState.currentTransform()->isSimple(); } // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t drawColor(int color, SkXfermode::Mode mode); + virtual void drawColor(int color, SkXfermode::Mode mode) override; // Bitmap-based - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) override; + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, const SkPaint* paint); - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, - const float* vertices, const int* colors, const SkPaint* paint); - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, - float left, float top, float right, float bottom, const SkPaint* paint); + float dstRight, float dstBottom, const SkPaint* paint) override; + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) override; + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint) override; + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + float left, float top, float right, float bottom, const SkPaint* paint) override; // Shapes - virtual status_t drawRect(float left, float top, float right, float bottom, - const SkPaint* paint); - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); - virtual status_t drawRoundRect(float left, float top, float right, float bottom, - float rx, float ry, const SkPaint* paint); - virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, + virtual void drawRect(float left, float top, float right, float bottom, + const SkPaint* paint) override; + virtual void drawRects(const float* rects, int count, const SkPaint* paint) override; + virtual void drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, const SkPaint* paint) override; + virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, CanvasPropertyPaint* paint); - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint); - virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) override; + virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint); - virtual status_t drawOval(float left, float top, float right, float bottom, - const SkPaint* paint); - virtual status_t drawArc(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint); - virtual status_t drawPath(const SkPath* path, const SkPaint* paint); - virtual status_t drawLines(const float* points, int count, const SkPaint* paint); - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint); + virtual void drawOval(float left, float top, float right, float bottom, + const SkPaint* paint) override; + virtual void drawArc(float left, float top, float right, float bottom, + float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) override; + virtual void drawPath(const SkPath* path, const SkPaint* paint) override; + virtual void drawLines(const float* points, int count, const SkPaint* paint) override; + virtual void drawPoints(const float* points, int count, const SkPaint* paint) override; // Text - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, - DrawOpMode drawOpMode = kDrawOpMode_Immediate); - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, - float hOffset, float vOffset, const SkPaint* paint); - virtual status_t drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint); + DrawOpMode drawOpMode = kDrawOpMode_Immediate) override; + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + float hOffset, float vOffset, const SkPaint* paint) override; + virtual void drawPosText(const char* text, int bytesCount, int count, + const float* positions, const SkPaint* paint) override; // ---------------------------------------------------------------------------- // Canvas draw operations - special // ---------------------------------------------------------------------------- - virtual status_t drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); - virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); + virtual void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); + virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) override; // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + virtual void callDrawGLFunction(Functor* functor, Rect& dirty) override; void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } + +// ---------------------------------------------------------------------------- +// CanvasState callbacks +// ---------------------------------------------------------------------------- + virtual void onViewportInitialized() override { } + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { } + virtual GLuint onGetTargetFbo() const override { return -1; } + private: + + CanvasState mState; + enum DeferredBarrierType { kBarrier_None, kBarrier_InOrder, @@ -186,7 +220,7 @@ private: template<class T> inline const T* refBuffer(const T* srcBuffer, int32_t count) { - if (!srcBuffer) return NULL; + if (!srcBuffer) return nullptr; T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T)); memcpy(dstBuffer, srcBuffer, count * sizeof(T)); @@ -198,58 +232,62 @@ private: } inline const SkPath* refPath(const SkPath* path) { - if (!path) return NULL; + if (!path) return nullptr; - const SkPath* pathCopy = mPathMap.valueFor(path); - if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { + const SkPath* cachedPath = mPathMap.valueFor(path); + if (cachedPath == nullptr || cachedPath->getGenerationID() != path->getGenerationID()) { SkPath* newPathCopy = new SkPath(*path); newPathCopy->setSourcePath(path); + cachedPath = newPathCopy; + std::unique_ptr<const SkPath> copy(newPathCopy); + mDisplayListData->paths.push_back(std::move(copy)); - pathCopy = newPathCopy; // replaceValueFor() performs an add if the entry doesn't exist - mPathMap.replaceValueFor(path, pathCopy); - mDisplayListData->paths.add(pathCopy); + mPathMap.replaceValueFor(path, cachedPath); } if (mDisplayListData->sourcePaths.indexOf(path) < 0) { mResourceCache.incrementRefcount(path); mDisplayListData->sourcePaths.add(path); } - return pathCopy; + return cachedPath; } inline const SkPaint* refPaint(const SkPaint* paint) { - if (!paint) return NULL; - - const SkPaint* paintCopy = mPaintMap.valueFor(paint); - if (paintCopy == NULL - || paintCopy->getGenerationID() != paint->getGenerationID() - // We can't compare shader pointers because that will always - // change as we do partial copying via wrapping. However, if the - // shader changes the paint generationID will have changed and - // so we don't hit this comparison anyway - || !(paint->getShader() && paintCopy->getShader() - && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { - paintCopy = copyPaint(paint); + if (!paint) return nullptr; + + // If there is a draw filter apply it here and store the modified paint + // so that we don't need to modify the paint every time we access it. + SkTLazy<SkPaint> filteredPaint; + if (mDrawFilter.get()) { + paint = filteredPaint.init(); + mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type); + } + + // compute the hash key for the paint and check the cache. + const uint32_t key = paint->getHash(); + const SkPaint* cachedPaint = mPaintMap.valueFor(key); + // In the unlikely event that 2 unique paints have the same hash we do a + // object equality check to ensure we don't erroneously dedup them. + if (cachedPaint == nullptr || *cachedPaint != *paint) { + cachedPaint = new SkPaint(*paint); + std::unique_ptr<const SkPaint> copy(cachedPaint); + mDisplayListData->paints.push_back(std::move(copy)); + // replaceValueFor() performs an add if the entry doesn't exist - mPaintMap.replaceValueFor(paint, paintCopy); + mPaintMap.replaceValueFor(key, cachedPaint); } - return paintCopy; + return cachedPaint; } inline SkPaint* copyPaint(const SkPaint* paint) { - if (!paint) return NULL; - SkPaint* paintCopy = new SkPaint(*paint); - if (paint->getShader()) { - SkShader* shaderCopy = SkShader::CreateLocalMatrixShader( - paint->getShader(), paint->getShader()->getLocalMatrix()); - paintCopy->setShader(shaderCopy); - paintCopy->setGenerationID(paint->getGenerationID()); - shaderCopy->setGenerationID(paint->getShader()->getGenerationID()); - shaderCopy->unref(); - } - mDisplayListData->paints.add(paintCopy); - return paintCopy; + if (!paint) return nullptr; + + SkPaint* returnPaint = new SkPaint(*paint); + std::unique_ptr<const SkPaint> copy(returnPaint); + mDisplayListData->paints.push_back(std::move(copy)); + + return returnPaint; } inline const SkRegion* refRegion(const SkRegion* region) { @@ -257,16 +295,18 @@ private: return region; } - const SkRegion* regionCopy = mRegionMap.valueFor(region); + const SkRegion* cachedRegion = mRegionMap.valueFor(region); // TODO: Add generation ID to SkRegion - if (regionCopy == NULL) { - regionCopy = new SkRegion(*region); + if (cachedRegion == nullptr) { + std::unique_ptr<const SkRegion> copy(new SkRegion(*region)); + cachedRegion = copy.get(); + mDisplayListData->regions.push_back(std::move(copy)); + // replaceValueFor() performs an add if the entry doesn't exist - mRegionMap.replaceValueFor(region, regionCopy); - mDisplayListData->regions.add(regionCopy); + mRegionMap.replaceValueFor(region, cachedRegion); } - return regionCopy; + return cachedRegion; } inline const SkBitmap* refBitmap(const SkBitmap* bitmap) { @@ -291,7 +331,7 @@ private: return patch; } - DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap; + DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap; DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; @@ -306,6 +346,8 @@ private: int mRestoreSaveCount; + SkAutoTUnref<SkDrawFilter> mDrawFilter; + friend class RenderNode; }; // class DisplayListRenderer diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h index 546236be18c7..092ebf283d6b 100644 --- a/libs/hwui/Dither.h +++ b/libs/hwui/Dither.h @@ -19,12 +19,11 @@ #include <GLES3/gl3.h> -#include "Program.h" - namespace android { namespace uirenderer { class Caches; +class Program; // Must be a power of two #define DITHER_KERNEL_SIZE 4 diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h index f175e98eea63..fc29f7ac1e5b 100644 --- a/libs/hwui/Fence.h +++ b/libs/hwui/Fence.h @@ -43,7 +43,7 @@ public: Fence() { mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (mDisplay != EGL_NO_DISPLAY) { - mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL); + mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, nullptr); } else { mFence = EGL_NO_SYNC_KHR; } diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 5b5b09820670..693afcdb7bde 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -770,15 +770,12 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, flo } #endif - float *gaussian = new float[2 * intRadius + 1]; - Blur::generateGaussianWeights(gaussian, intRadius); + std::unique_ptr<float[]> gaussian(new float[2 * intRadius + 1]); + Blur::generateGaussianWeights(gaussian.get(), intRadius); - uint8_t* scratch = new uint8_t[width * height]; - Blur::horizontal(gaussian, intRadius, *image, scratch, width, height); - Blur::vertical(gaussian, intRadius, scratch, *image, width, height); - - delete[] gaussian; - delete[] scratch; + std::unique_ptr<uint8_t[]> scratch(new uint8_t[width * height]); + Blur::horizontal(gaussian.get(), intRadius, *image, scratch.get(), width, height); + Blur::vertical(gaussian.get(), intRadius, scratch.get(), *image, width, height); } static uint32_t calculateCacheSize(const Vector<CacheTexture*>& cacheTextures) { diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index 5c96c6b41c59..668ee6488fcc 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -31,8 +31,6 @@ #include "font/CachedGlyphInfo.h" #include "font/Font.h" #include "utils/SortedList.h" -#include "Matrix.h" -#include "Properties.h" #ifdef ANDROID_ENABLE_RENDERSCRIPT #include "RenderScript.h" @@ -68,7 +66,7 @@ public: } ~TextSetupFunctor() { } - status_t operator ()(int what, void* data); + status_t operator ()(int what, void* data) override; OpenGLRenderer* renderer; float x; diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp index 06d2aad12f2a..0a98c29d2044 100644 --- a/libs/hwui/GammaFontRenderer.cpp +++ b/libs/hwui/GammaFontRenderer.cpp @@ -183,12 +183,6 @@ Lookup3GammaFontRenderer::Lookup3GammaFontRenderer(): GammaFontRenderer() { memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount); } -Lookup3GammaFontRenderer::~Lookup3GammaFontRenderer() { - for (int i = 0; i < kGammaCount; i++) { - delete mRenderers[i]; - } -} - void Lookup3GammaFontRenderer::endPrecaching() { for (int i = 0; i < kGammaCount; i++) { if (mRenderers[i]) { @@ -199,8 +193,7 @@ void Lookup3GammaFontRenderer::endPrecaching() { void Lookup3GammaFontRenderer::clear() { for (int i = 0; i < kGammaCount; i++) { - delete mRenderers[i]; - mRenderers[i] = NULL; + mRenderers[i].release(); } } @@ -221,8 +214,7 @@ void Lookup3GammaFontRenderer::flush() { if (count <= 1 || min < 0) return; - delete mRenderers[min]; - mRenderers[min] = NULL; + mRenderers[min].release(); // Also eliminate the caches for large glyphs, as they consume significant memory for (int i = 0; i < kGammaCount; ++i) { @@ -233,14 +225,12 @@ void Lookup3GammaFontRenderer::flush() { } FontRenderer* Lookup3GammaFontRenderer::getRenderer(Gamma gamma) { - FontRenderer* renderer = mRenderers[gamma]; - if (!renderer) { - renderer = new FontRenderer(); - mRenderers[gamma] = renderer; - renderer->setGammaTable(&mGammaTable[gamma * 256]); + if (!mRenderers[gamma]) { + mRenderers[gamma].reset(new FontRenderer()); + mRenderers[gamma]->setGammaTable(&mGammaTable[gamma * 256]); } mRenderersUsageCount[gamma]++; - return renderer; + return mRenderers[gamma].get(); } FontRenderer& Lookup3GammaFontRenderer::getFontRenderer(const SkPaint* paint) { diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h index 46cfd04d9ccc..19352d721a22 100644 --- a/libs/hwui/GammaFontRenderer.h +++ b/libs/hwui/GammaFontRenderer.h @@ -59,36 +59,36 @@ public: delete mRenderer; } - void clear() { + void clear() override { delete mRenderer; - mRenderer = NULL; + mRenderer = nullptr; } - void flush() { + void flush() override { if (mRenderer) { mRenderer->flushLargeCaches(); } } - FontRenderer& getFontRenderer(const SkPaint* paint) { + FontRenderer& getFontRenderer(const SkPaint* paint) override { if (!mRenderer) { mRenderer = new FontRenderer; } return *mRenderer; } - uint32_t getFontRendererCount() const { + uint32_t getFontRendererCount() const override { return 1; } - uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const { + uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const override { return mRenderer ? mRenderer->getCacheSize(format) : 0; } - void describe(ProgramDescription& description, const SkPaint* paint) const; - void setupProgram(ProgramDescription& description, Program* program) const; + void describe(ProgramDescription& description, const SkPaint* paint) const override; + void setupProgram(ProgramDescription& description, Program* program) const override; - void endPrecaching(); + void endPrecaching() override; private: ShaderGammaFontRenderer(bool multiGamma); @@ -105,18 +105,18 @@ public: delete mRenderer; } - void clear() { + void clear() override { delete mRenderer; - mRenderer = NULL; + mRenderer = nullptr; } - void flush() { + void flush() override { if (mRenderer) { mRenderer->flushLargeCaches(); } } - FontRenderer& getFontRenderer(const SkPaint* paint) { + FontRenderer& getFontRenderer(const SkPaint* paint) override { if (!mRenderer) { mRenderer = new FontRenderer; mRenderer->setGammaTable(&mGammaTable[0]); @@ -124,21 +124,21 @@ public: return *mRenderer; } - uint32_t getFontRendererCount() const { + uint32_t getFontRendererCount() const override { return 1; } - uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const { + uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const override { return mRenderer ? mRenderer->getCacheSize(format) : 0; } - void describe(ProgramDescription& description, const SkPaint* paint) const { + void describe(ProgramDescription& description, const SkPaint* paint) const override { } - void setupProgram(ProgramDescription& description, Program* program) const { + void setupProgram(ProgramDescription& description, Program* program) const override { } - void endPrecaching(); + void endPrecaching() override; private: LookupGammaFontRenderer(); @@ -151,33 +151,30 @@ private: class Lookup3GammaFontRenderer: public GammaFontRenderer { public: - ~Lookup3GammaFontRenderer(); + void clear() override; + void flush() override; - void clear(); - void flush(); + FontRenderer& getFontRenderer(const SkPaint* paint) override; - FontRenderer& getFontRenderer(const SkPaint* paint); - - uint32_t getFontRendererCount() const { + uint32_t getFontRendererCount() const override { return kGammaCount; } - uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const { + uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const override { if (fontRenderer >= kGammaCount) return 0; - FontRenderer* renderer = mRenderers[fontRenderer]; - if (!renderer) return 0; + if (!mRenderers[fontRenderer]) return 0; - return renderer->getCacheSize(format); + return mRenderers[fontRenderer]->getCacheSize(format); } - void describe(ProgramDescription& description, const SkPaint* paint) const { + void describe(ProgramDescription& description, const SkPaint* paint) const override { } - void setupProgram(ProgramDescription& description, Program* program) const { + void setupProgram(ProgramDescription& description, Program* program) const override { } - void endPrecaching(); + void endPrecaching() override; private: Lookup3GammaFontRenderer(); @@ -192,7 +189,7 @@ private: FontRenderer* getRenderer(Gamma gamma); uint32_t mRenderersUsageCount[kGammaCount]; - FontRenderer* mRenderers[kGammaCount]; + std::unique_ptr<FontRenderer> mRenderers[kGammaCount]; uint8_t mGammaTable[256 * kGammaCount]; diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index ffd1e8c98003..06d234c69783 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -52,10 +52,10 @@ int GradientCacheEntry::compare(const GradientCacheEntry& lhs, const GradientCac int deltaInt = int(lhs.count) - int(rhs.count); if (deltaInt != 0) return deltaInt; - deltaInt = memcmp(lhs.colors, rhs.colors, lhs.count * sizeof(uint32_t)); + deltaInt = memcmp(lhs.colors.get(), rhs.colors.get(), lhs.count * sizeof(uint32_t)); if (deltaInt != 0) return deltaInt; - return memcmp(lhs.positions, rhs.positions, lhs.count * sizeof(float)); + return memcmp(lhs.positions.get(), rhs.positions.get(), lhs.count * sizeof(float)); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 6a783b15b383..9176c763a65d 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -25,16 +25,16 @@ #include <utils/Mutex.h> #include <utils/Vector.h> -#include "Texture.h" - namespace android { namespace uirenderer { +class Texture; + struct GradientCacheEntry { GradientCacheEntry() { count = 0; - colors = NULL; - positions = NULL; + colors = nullptr; + positions = nullptr; } GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) { @@ -42,20 +42,12 @@ struct GradientCacheEntry { } GradientCacheEntry(const GradientCacheEntry& entry) { - copy(entry.colors, entry.positions, entry.count); - } - - ~GradientCacheEntry() { - delete[] colors; - delete[] positions; + copy(entry.colors.get(), entry.positions.get(), entry.count); } GradientCacheEntry& operator=(const GradientCacheEntry& entry) { if (this != &entry) { - delete[] colors; - delete[] positions; - - copy(entry.colors, entry.positions, entry.count); + copy(entry.colors.get(), entry.positions.get(), entry.count); } return *this; @@ -73,18 +65,18 @@ struct GradientCacheEntry { return compare(*this, other) != 0; } - uint32_t* colors; - float* positions; + std::unique_ptr<uint32_t[]> colors; + std::unique_ptr<float[]> positions; uint32_t count; private: void copy(uint32_t* colors, float* positions, uint32_t count) { this->count = count; - this->colors = new uint32_t[count]; - this->positions = new float[count]; + this->colors.reset(new uint32_t[count]); + this->positions.reset(new float[count]); - memcpy(this->colors, colors, count * sizeof(uint32_t)); - memcpy(this->positions, positions, count * sizeof(float)); + memcpy(this->colors.get(), colors, count * sizeof(uint32_t)); + memcpy(this->positions.get(), positions, count * sizeof(float)); } }; // GradientCacheEntry @@ -118,7 +110,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(GradientCacheEntry& shader, Texture*& texture); + void operator()(GradientCacheEntry& shader, Texture*& texture) override; /** * Returns the texture associated with the specified shader. diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp index 0e62d7780780..e1b0fc3937c5 100644 --- a/libs/hwui/Interpolator.cpp +++ b/libs/hwui/Interpolator.cpp @@ -14,12 +14,6 @@ * limitations under the License. */ -// LOG_TAG is being provided by the Makefile, reset. -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "Interpolator" - #include "Interpolator.h" #include <cmath> @@ -94,14 +88,12 @@ float OvershootInterpolator::interpolate(float t) { return t * t * ((mTension + 1) * t + mTension) + 1.0f; } -LUTInterpolator::LUTInterpolator(float* values, size_t size) { - mValues = values; - mSize = size; +LUTInterpolator::LUTInterpolator(float* values, size_t size) + : mValues(values) + , mSize(size) { } LUTInterpolator::~LUTInterpolator() { - delete mValues; - mValues = 0; } float LUTInterpolator::interpolate(float input) { @@ -118,7 +110,7 @@ float LUTInterpolator::interpolate(float input) { LOG_ALWAYS_FATAL_IF(i1 < 0 || i2 < 0, "negatives in interpolation!" " i1=%d, i2=%d, input=%f, lutpos=%f, size=%zu, values=%p, ipart=%f, weight=%f", - i1, i2, input, lutpos, mSize, mValues, ipart, weight); + i1, i2, input, lutpos, mSize, mValues.get(), ipart, weight); float v1 = mValues[i1]; float v2 = mValues[i2]; diff --git a/libs/hwui/Interpolator.h b/libs/hwui/Interpolator.h index dfa0a85bce41..e636e11e1b8c 100644 --- a/libs/hwui/Interpolator.h +++ b/libs/hwui/Interpolator.h @@ -17,6 +17,7 @@ #define INTERPOLATOR_H #include <stddef.h> +#include <memory> #include <cutils/compiler.h> @@ -107,7 +108,7 @@ public: virtual float interpolate(float input); private: - float* mValues; + std::unique_ptr<float[]> mValues; size_t mSize; }; diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 9aa29ca184d0..8e77c5cb398c 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -54,14 +54,12 @@ Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth texture.height = layerHeight; colorFilter = NULL; deferredUpdateScheduled = false; - renderer = NULL; renderNode = NULL; fbo = 0; stencil = NULL; debugDrawUpdate = false; hasDrawnSinceUpdate = false; forceFilter = false; - deferredList = NULL; convexMask = NULL; rendererLightPosDirty = true; wasBuildLayered = false; @@ -76,8 +74,6 @@ Layer::~Layer() { deleteTexture(); delete[] mesh; - delete deferredList; - delete renderer; } uint32_t Layer::computeIdealWidth(uint32_t layerWidth) { @@ -90,7 +86,7 @@ uint32_t Layer::computeIdealHeight(uint32_t layerHeight) { void Layer::requireRenderer() { if (!renderer) { - renderer = new LayerRenderer(renderState, this); + renderer.reset(new LayerRenderer(renderState, this)); renderer->initProperties(); } } @@ -241,8 +237,7 @@ void Layer::defer(const OpenGLRenderer& rootRenderer) { dirtyRect.set(0, 0, width, height); } - delete deferredList; - deferredList = new DeferredDisplayList(dirtyRect); + deferredList.reset(new DeferredDisplayList(dirtyRect)); DeferStateStruct deferredState(*deferredList, *renderer, RenderNode::kReplayFlag_ClipChildren); @@ -260,10 +255,7 @@ void Layer::defer(const OpenGLRenderer& rootRenderer) { void Layer::cancelDefer() { renderNode = NULL; deferredUpdateScheduled = false; - if (deferredList) { - delete deferredList; - deferredList = NULL; - } + deferredList.release(); } void Layer::flush() { diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 2d6a72717b45..3b4f293dddd3 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -20,6 +20,8 @@ #include <cutils/compiler.h> #include <sys/types.h> #include <utils/StrongPointer.h> +#include <utils/RefBase.h> +#include <memory> #include <GLES2/gl2.h> @@ -43,9 +45,9 @@ namespace uirenderer { // Forward declarations class Caches; +class RenderNode; class RenderState; class OpenGLRenderer; -class RenderNode; class DeferredDisplayList; struct DeferStateStruct; @@ -319,7 +321,7 @@ public: * Used for deferred updates. */ bool deferredUpdateScheduled; - OpenGLRenderer* renderer; + std::unique_ptr<OpenGLRenderer> renderer; sp<RenderNode> renderNode; Rect dirtyRect; bool debugDrawUpdate; @@ -416,7 +418,7 @@ private: * Used to defer display lists when the layer is updated with a * display list. */ - DeferredDisplayList* deferredList; + std::unique_ptr<DeferredDisplayList> deferredList; /** * This convex path should be used to mask the layer's draw to the screen. diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index 3216cd2d91d4..d6703f2e5c47 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -80,10 +80,8 @@ int LayerCache::LayerEntry::compare(const LayerCache::LayerEntry& lhs, void LayerCache::deleteLayer(Layer* layer) { if (layer) { - if (kDebugLayers) { - ALOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(), - layer->getFbo()); - } + LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(), + layer->getFbo()); mSize -= layer->getWidth() * layer->getHeight() * 4; layer->state = Layer::kState_DeletedFromCache; layer->decStrong(0); @@ -112,13 +110,9 @@ Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uin layer->state = Layer::kState_RemovedFromCache; mSize -= layer->getWidth() * layer->getHeight() * 4; - if (kDebugLayers) { - ALOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight()); - } + LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight()); } else { - if (kDebugLayers) { - ALOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight); - } + LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight); layer = new Layer(Layer::kType_DisplayList, renderState, entry.mWidth, entry.mHeight); layer->setBlend(true); @@ -143,9 +137,7 @@ void LayerCache::dump() { size_t size = mCache.size(); for (size_t i = 0; i < size; i++) { const LayerEntry& entry = mCache.itemAt(i); - if (kDebugLayers) { - ALOGD(" Layer size %dx%d", entry.mWidth, entry.mHeight); - } + ALOGD(" Layer size %dx%d", entry.mWidth, entry.mHeight); } } @@ -165,10 +157,8 @@ bool LayerCache::put(Layer* layer) { deleteLayer(victim); mCache.removeAt(position); - if (kDebugLayers) { - ALOGD(" Deleting layer %.2fx%.2f", victim->layer.getWidth(), - victim->layer.getHeight()); - } + LAYER_LOGD(" Deleting layer %.2fx%.2f", victim->layer.getWidth(), + victim->layer.getHeight()); } layer->cancelDefer(); diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h index 81810acef163..7d17b9ba41aa 100644 --- a/libs/hwui/LayerCache.h +++ b/libs/hwui/LayerCache.h @@ -26,11 +26,14 @@ namespace uirenderer { class RenderState; -// Debug +/////////////////////////////////////////////////////////////////////////////// +// Defines +/////////////////////////////////////////////////////////////////////////////// + #if DEBUG_LAYERS -static const bool kDebugLayers = true; + #define LAYER_LOGD(...) ALOGD(__VA_ARGS__) #else -static const bool kDebugLayers = false; + #define LAYER_LOGD(...) #endif /////////////////////////////////////////////////////////////////////////////// @@ -93,10 +96,10 @@ public: private: struct LayerEntry { LayerEntry(): - mLayer(NULL), mWidth(0), mHeight(0) { + mLayer(nullptr), mWidth(0), mHeight(0) { } - LayerEntry(const uint32_t layerWidth, const uint32_t layerHeight): mLayer(NULL) { + LayerEntry(const uint32_t layerWidth, const uint32_t layerHeight): mLayer(nullptr) { mWidth = Layer::computeIdealWidth(layerWidth); mHeight = Layer::computeIdealHeight(layerHeight); } diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 83f9c6a07437..fc3a3b2a277b 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -44,7 +44,7 @@ LayerRenderer::LayerRenderer(RenderState& renderState, Layer* layer) LayerRenderer::~LayerRenderer() { } -status_t LayerRenderer::prepareDirty(float left, float top, float right, float bottom, +void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo()); @@ -65,25 +65,23 @@ status_t LayerRenderer::prepareDirty(float left, float top, float right, float b } mLayer->clipRect.set(dirty); - return OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque); + OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque); } -status_t LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) { +void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (mLayer->isDirty()) { getCaches().disableScissor(); glClear(GL_COLOR_BUFFER_BIT); getCaches().resetScissor(); mLayer->setDirty(false); - - return DrawGlInfo::kStatusDone; + } else { + OpenGLRenderer::clear(left, top, right, bottom, opaque); } - - return OpenGLRenderer::clear(left, top, right, bottom, opaque); } -void LayerRenderer::finish() { - OpenGLRenderer::finish(); +bool LayerRenderer::finish() { + bool retval = OpenGLRenderer::finish(); generateMesh(); @@ -91,9 +89,10 @@ void LayerRenderer::finish() { // No need to unbind our FBO, this will be taken care of by the caller // who will invoke OpenGLRenderer::resume() + return retval; } -GLuint LayerRenderer::getTargetFbo() const { +GLuint LayerRenderer::onGetTargetFbo() const { return mLayer->getFbo(); } @@ -118,7 +117,7 @@ void LayerRenderer::ensureStencilBuffer() { /////////////////////////////////////////////////////////////////////////////// Region* LayerRenderer::getRegion() const { - if (currentSnapshot()->flags & Snapshot::kFlagFboTarget) { + if (mState.currentFlags() & Snapshot::kFlagFboTarget) { return OpenGLRenderer::getRegion(); } return &mLayer->region; diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 4d8620b8a4ea..769ef4937e9a 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -50,9 +50,9 @@ public: virtual ~LayerRenderer(); virtual void onViewportInitialized() { /* do nothing */ } - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual status_t clear(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); + virtual void clear(float left, float top, float right, float bottom, bool opaque); + virtual bool finish(); static Layer* createTextureLayer(RenderState& renderState); static Layer* createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height); @@ -68,7 +68,7 @@ protected: virtual void ensureStencilBuffer(); virtual bool hasLayer() const; virtual Region* getRegion() const; - virtual GLuint getTargetFbo() const; + virtual GLuint onGetTargetFbo() const; virtual bool suppressErrorChecks() const; private: diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 1c5c5783bde9..a76013503d5f 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -210,7 +210,7 @@ public: void decomposeScale(float& sx, float& sy) const; - void dump(const char* label = NULL) const; + void dump(const char* label = nullptr) const; static const Matrix4& identity(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 355a31f3802c..fb3d462e8f59 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -36,15 +36,18 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" -#include "RenderState.h" +#include "GammaFontRenderer.h" +#include "Patch.h" #include "PathTessellator.h" #include "Properties.h" +#include "RenderNode.h" +#include "RenderState.h" #include "ShadowTessellator.h" #include "SkiaShader.h" -#include "utils/GLUtils.h" -#include "utils/TraceUtils.h" #include "Vector.h" #include "VertexBuffer.h" +#include "utils/GLUtils.h" +#include "utils/TraceUtils.h" #if DEBUG_DETAILED_EVENTS #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__) @@ -130,13 +133,15 @@ static inline T min(T a, T b) { /////////////////////////////////////////////////////////////////////////////// OpenGLRenderer::OpenGLRenderer(RenderState& renderState) - : mFrameStarted(false) + : mState(*this) + , mFrameStarted(false) , mCaches(Caches::getInstance()) , mExtensions(Extensions::getInstance()) , mRenderState(renderState) , mScissorOptimizationDisabled(false) , mSuppressTiling(false) , mFirstFrameAfterResize(true) + , mDirty(false) , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN}) , mLightRadius(FLT_MIN) , mAmbientShadowAlpha(0) @@ -187,20 +192,20 @@ void OpenGLRenderer::onViewportInitialized() { void OpenGLRenderer::setupFrameState(float left, float top, float right, float bottom, bool opaque) { mCaches.clearGarbage(); - initializeSaveStack(left, top, right, bottom, mLightCenter); + mState.initializeSaveStack(left, top, right, bottom, mLightCenter); mOpaque = opaque; mTilingClip.set(left, top, right, bottom); } -status_t OpenGLRenderer::startFrame() { - if (mFrameStarted) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::startFrame() { + if (mFrameStarted) return; mFrameStarted = true; - mDirtyClip = true; + mState.setDirtyClip(true); discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom); - mRenderState.setViewport(getWidth(), getHeight()); + mRenderState.setViewport(mState.getWidth(), mState.getHeight()); // Functors break the tiling extension in pretty spectacular ways // This ensures we don't use tiling when a functor is going to be @@ -213,11 +218,11 @@ status_t OpenGLRenderer::startFrame() { debugOverdraw(true, true); - return clear(mTilingClip.left, mTilingClip.top, + clear(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom, mOpaque); } -status_t OpenGLRenderer::prepareDirty(float left, float top, +void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { setupFrameState(left, top, right, bottom, opaque); @@ -230,10 +235,8 @@ status_t OpenGLRenderer::prepareDirty(float left, float top, syncState(); updateLayers(); } else { - return startFrame(); + startFrame(); } - - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::discardFramebuffer(float left, float top, float right, float bottom) { @@ -241,8 +244,8 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa // perform a discard to let the driver know we don't need to preserve // the back buffer for this frame. if (mExtensions.hasDiscardFramebuffer() && - left <= 0.0f && top <= 0.0f && right >= getWidth() && bottom >= getHeight()) { - const bool isFbo = getTargetFbo() == 0; + left <= 0.0f && top <= 0.0f && right >= mState.getWidth() && bottom >= mState.getHeight()) { + const bool isFbo = onGetTargetFbo() == 0; const GLenum attachments[] = { isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0, isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT }; @@ -250,16 +253,16 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa } } -status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { +void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top); glClear(GL_COLOR_BUFFER_BIT); - return DrawGlInfo::kStatusDrew; + mDirty = true; + return; } mCaches.resetScissor(); - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::syncState() { @@ -307,18 +310,14 @@ void OpenGLRenderer::endTiling() { if (!mSuppressTiling) mCaches.endTiling(); } -void OpenGLRenderer::finish() { +bool OpenGLRenderer::finish() { renderOverdraw(); endTiling(); - - for (size_t i = 0; i < mTempPaths.size(); i++) { - delete mTempPaths[i]; - } mTempPaths.clear(); // When finish() is invoked on FBO 0 we've reached the end // of the current frame - if (getTargetFbo() == 0) { + if (onGetTargetFbo() == 0) { mCaches.pathCache.trim(); mCaches.tessellationCache.trim(); } @@ -338,6 +337,8 @@ void OpenGLRenderer::finish() { } mFrameStarted = false; + + return reportAndClearDirty(); } void OpenGLRenderer::resumeAfterLayer() { @@ -349,10 +350,10 @@ void OpenGLRenderer::resumeAfterLayer() { dirtyClip(); } -status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); // Since we don't know what the functor will draw, let's dirty @@ -371,9 +372,9 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.height = getViewportHeight(); currentTransform()->copyTo(&info.transform[0]); - bool prevDirtyClip = mDirtyClip; + bool prevDirtyClip = mState.getDirtyClip(); // setup GL state for functor - if (mDirtyClip) { + if (mState.getDirtyClip()) { setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt() } if (mCaches.enableScissor() || prevDirtyClip) { @@ -384,7 +385,7 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { // Scissor may have been modified, reset dirty clip dirtyClip(); - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// @@ -402,8 +403,6 @@ void OpenGLRenderer::eventMarkDEBUG(const char* fmt, ...) const { va_end(ap); eventMark(buf); -#else - (void)fmt; #endif } @@ -425,11 +424,11 @@ void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { } void OpenGLRenderer::renderOverdraw() { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { + if (mCaches.debugOverdraw && onGetTargetFbo() == 0) { const Rect* clip = &mTilingClip; mCaches.enableScissor(); - mCaches.setScissor(clip->left, firstSnapshot()->getViewportHeight() - clip->bottom, + mCaches.setScissor(clip->left, mState.firstSnapshot()->getViewportHeight() - clip->bottom, clip->right - clip->left, clip->bottom - clip->top); // 1x overdraw @@ -505,7 +504,7 @@ void OpenGLRenderer::updateLayers() { if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); } endMark(); } @@ -522,7 +521,7 @@ void OpenGLRenderer::flushLayers() { } mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); endMark(); } @@ -604,9 +603,9 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, // force matrix/clip isolation for layer flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { createLayer(left, top, right, bottom, paint, flags, convexMask); } @@ -619,7 +618,7 @@ void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool currentTransform()->mapRect(bounds); // Layers only make sense if they are in the framebuffer's bounds - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { // We cannot work with sub-pixels in this case bounds.snapToPixelBoundaries(); @@ -653,17 +652,17 @@ void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize || bounds.getHeight() > mCaches.maxTextureSize || (fboLayer && clip.isEmpty())) { - mSnapshot->empty = fboLayer; + writableSnapshot()->empty = fboLayer; } else { - mSnapshot->invisible = mSnapshot->invisible || (alpha <= 0 && fboLayer); + writableSnapshot()->invisible = writableSnapshot()->invisible || (alpha <= 0 && fboLayer); } } int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom, const SkPaint* paint, int flags) { - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { + if (!mState.currentlyIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { // initialize the snapshot as though it almost represents an FBO layer so deferred draw // operations will be able to store and restore the current clip and transform info, and // quick rejection will be correct (for display lists) @@ -673,11 +672,11 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float calculateLayerBoundsAndClip(bounds, clip, true); updateSnapshotIgnoreForLayer(bounds, clip, true, getAlphaDirect(paint)); - if (!currentSnapshot()->isIgnored()) { - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + if (!mState.currentlyIgnored()) { + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = nullptr; } } @@ -737,10 +736,8 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float */ bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom, const SkPaint* paint, int flags, const SkPath* convexMask) { - if (kDebugLayers) { - ALOGD("Requesting layer %.2fx%.2f", right - left, bottom - top); - ALOGD("Layer cache size = %d", mCaches.layerCache.getSize()); - } + LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top); + LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize()); const bool fboLayer = flags & SkCanvas::kClipToLayer_SaveFlag; @@ -751,7 +748,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, getAlphaDirect(paint)); // Bail out if we won't draw in this snapshot - if (currentSnapshot()->isIgnored()) { + if (mState.currentlyIgnored()) { return false; } @@ -771,8 +768,8 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache // Save the layer in the snapshot - mSnapshot->flags |= Snapshot::kFlagIsLayer; - mSnapshot->layer = layer; + writableSnapshot()->flags |= Snapshot::kFlagIsLayer; + writableSnapshot()->layer = layer; ATRACE_FORMAT_BEGIN("%ssaveLayer %ux%u", fboLayer ? "" : "unclipped ", @@ -790,7 +787,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto // Unfortunately some drivers will turn the entire target texture black // when reading outside of the window. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->getWidth(), layer->getHeight(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); layer->setEmpty(false); } @@ -799,7 +796,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto bounds.getWidth(), bounds.getHeight()); // Enqueue the buffer coordinates to clear the corresponding region later - mLayers.push(new Rect(bounds)); + mLayers.push_back(Rect(bounds)); } } @@ -810,13 +807,13 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { layer->clipRect.set(clip); layer->setFbo(mCaches.fboCache.get()); - mSnapshot->region = &mSnapshot->layer->region; - mSnapshot->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; - mSnapshot->fbo = layer->getFbo(); - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + writableSnapshot()->region = &writableSnapshot()->layer->region; + writableSnapshot()->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; + writableSnapshot()->fbo = layer->getFbo(); + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = nullptr; endTiling(); debugOverdraw(false, false); @@ -863,8 +860,8 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; - calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, - &clipRequired, NULL, false); // safely ignore return, should never be rejected + mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, + &clipRequired, nullptr, false); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { @@ -908,7 +905,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto save(0); // the layer contains screen buffer content that shouldn't be alpha modulated // (and any necessary alpha modulation was handled drawing into the layer) - mSnapshot->alpha = 1.0f; + writableSnapshot()->alpha = 1.0f; composeLayerRect(layer, rect, true); restore(); } @@ -916,12 +913,10 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto dirtyClip(); // Failing to add the layer to the cache should happen only if the layer is too large - layer->setConvexMask(NULL); + layer->setConvexMask(nullptr); if (!mCaches.layerCache.put(layer)) { - if (kDebugLayers) { - ALOGD("Deleting layer"); - } - layer->decStrong(0); + LAYER_LOGD("Deleting layer"); + layer->decStrong(nullptr); } } @@ -1018,13 +1013,13 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) * operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used * by saveLayer's restore */ -#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ - DRAW_COMMAND; \ - if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \ - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ - DRAW_COMMAND; \ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ - } \ +#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ + DRAW_COMMAND; \ + if (CC_UNLIKELY(mCaches.debugOverdraw && onGetTargetFbo() == 0 && COND)) { \ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ + DRAW_COMMAND; \ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ + } \ } #define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND) @@ -1038,14 +1033,14 @@ public: , mLayer(layer) { } - virtual bool asACustomShader(void** data) const { + virtual bool asACustomShader(void** data) const override { if (data) { *data = static_cast<void*>(mLayer); } return true; } - virtual bool isOpaque() const { + virtual bool isOpaque() const override { return !mLayer->isBlend(); } @@ -1054,13 +1049,13 @@ protected: LOG_ALWAYS_FATAL("LayerShader should never be drawn with raster backend."); } - virtual void flatten(SkWriteBuffer&) const { + virtual void flatten(SkWriteBuffer&) const override { LOG_ALWAYS_FATAL("LayerShader should never be flattened."); } - virtual Factory getFactory() const { + virtual Factory getFactory() const override { LOG_ALWAYS_FATAL("LayerShader should never be created from a stream."); - return NULL; + return nullptr; } private: // Unowned. @@ -1093,7 +1088,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const SkPath* maskPath = layer->getConvexMask(); DRAW_DOUBLE_STENCIL(drawConvexPath(*maskPath, &paint)); - paint.setShader(NULL); + paint.setShader(nullptr); restore(); return; @@ -1174,7 +1169,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { if (numQuads >= gMaxNumberOfQuads) { DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6, - GL_UNSIGNED_SHORT, NULL)); + GL_UNSIGNED_SHORT, nullptr)); numQuads = 0; mesh = mCaches.getRegionMesh(); } @@ -1182,7 +1177,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { if (numQuads > 0) { DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6, - GL_UNSIGNED_SHORT, NULL)); + GL_UNSIGNED_SHORT, nullptr)); } #if DEBUG_LAYERS_AS_REGIONS @@ -1253,7 +1248,7 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top, } void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { bounds.snapToPixelBoundaries(); android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom); if (!dirty.isEmpty()) { @@ -1268,7 +1263,7 @@ void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) { GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); setupDrawIndexedVertices(&mesh[0].x); - glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL); + glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, nullptr); elementsCount -= drawCount; // Though there are 4 vertices in a quad, we use 6 indices per @@ -1281,7 +1276,7 @@ void OpenGLRenderer::clearLayerRegions() { const size_t count = mLayers.size(); if (count == 0) return; - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { EVENT_LOGD("clearLayerRegions"); // Doing several glScissor/glClear here can negatively impact // GPUs with a tiler architecture, instead we draw quads with @@ -1296,14 +1291,12 @@ void OpenGLRenderer::clearLayerRegions() { Vertex* vertex = mesh; for (uint32_t i = 0; i < count; i++) { - Rect* bounds = mLayers.itemAt(i); + const Rect& bounds = mLayers[i]; - Vertex::set(vertex++, bounds->left, bounds->top); - Vertex::set(vertex++, bounds->right, bounds->top); - Vertex::set(vertex++, bounds->left, bounds->bottom); - Vertex::set(vertex++, bounds->right, bounds->bottom); - - delete bounds; + Vertex::set(vertex++, bounds.left, bounds.top); + Vertex::set(vertex++, bounds.right, bounds.top); + Vertex::set(vertex++, bounds.left, bounds.bottom); + Vertex::set(vertex++, bounds.right, bounds.bottom); } // We must clear the list of dirty rects before we // call setupDraw() to prevent stencil setup to do @@ -1325,9 +1318,6 @@ void OpenGLRenderer::clearLayerRegions() { if (scissorChanged) mCaches.enableScissor(); } else { - for (uint32_t i = 0; i < count; i++) { - delete mLayers.itemAt(i); - } mLayers.clear(); } } @@ -1337,7 +1327,7 @@ void OpenGLRenderer::clearLayerRegions() { /////////////////////////////////////////////////////////////////////////////// bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) { - const Rect* currentClip = currentClipRect(); + const Rect* currentClip = mState.currentClipRect(); const mat4* currentMatrix = currentTransform(); if (stateDeferFlags & kStateDeferFlag_Draw) { @@ -1390,12 +1380,12 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) { setMatrix(state.mMatrix); - mSnapshot->alpha = state.mAlpha; + writableSnapshot()->alpha = state.mAlpha; mDrawModifiers = state.mDrawModifiers; - mSnapshot->roundRectClipState = state.mRoundRectClipState; + writableSnapshot()->roundRectClipState = state.mRoundRectClipState; if (state.mClipValid && !skipClipRestore) { - mSnapshot->setClip(state.mClip.left, state.mClip.top, + writableSnapshot()->setClip(state.mClip.left, state.mClip.top, state.mClip.right, state.mClip.bottom); dirtyClip(); } @@ -1409,13 +1399,13 @@ void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool * This method should be called when restoreDisplayState() won't be restoring the clip */ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { - if (clipRect != NULL) { - mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); + if (clipRect != nullptr) { + writableSnapshot()->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); } else { - mSnapshot->setClip(0, 0, getWidth(), getHeight()); + writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight()); } dirtyClip(); - mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled); + mCaches.setScissorEnabled(clipRect != nullptr || mScissorOptimizationDisabled); } /////////////////////////////////////////////////////////////////////////////// @@ -1423,12 +1413,12 @@ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setScissorFromClip() { - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); if (mCaches.setScissor(clip.left, getViewportHeight() - clip.bottom, clip.getWidth(), clip.getHeight())) { - mDirtyClip = false; + mState.setDirtyClip(false); } } @@ -1464,7 +1454,7 @@ void OpenGLRenderer::setStencilFromClip() { // NOTE: The order here is important, we must set dirtyClip to false // before any draw call to avoid calling back into this method - mDirtyClip = false; + mState.setDirtyClip(false); ensureStencilBuffer(); @@ -1533,7 +1523,7 @@ bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, bool clipRequired = false; bool roundRectClipRequired = false; - if (calculateQuickRejectForScissor(left, top, right, bottom, + if (mState.calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, &roundRectClipRequired, snapOut)) { return true; } @@ -1565,7 +1555,7 @@ void OpenGLRenderer::setupDraw(bool clearLayer) { if (clearLayer) clearLayerRegions(); // Make sure setScissor & setStencil happen at the beginning of // this method - if (mDirtyClip) { + if (mState.getDirtyClip()) { if (mCaches.scissorEnabled) { setScissorFromClip(); } @@ -1644,21 +1634,21 @@ void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) { } void OpenGLRenderer::setupDrawShader(const SkShader* shader) { - if (shader != NULL) { + if (shader != nullptr) { SkiaShader::describe(&mCaches, mDescription, mExtensions, *shader); } } void OpenGLRenderer::setupDrawColorFilter(const SkColorFilter* filter) { - if (filter == NULL) { + if (filter == nullptr) { return; } SkXfermode::Mode mode; - if (filter->asColorMode(NULL, &mode)) { + if (filter->asColorMode(nullptr, &mode)) { mDescription.colorOp = ProgramDescription::kColorBlend; mDescription.colorMode = mode; - } else if (filter->asColorMatrix(NULL)) { + } else if (filter->asColorMatrix(nullptr)) { mDescription.colorOp = ProgramDescription::kColorMatrix; } } @@ -1697,7 +1687,7 @@ void OpenGLRenderer::setupDrawProgram() { useProgram(mCaches.programCache.get(mDescription)); if (mDescription.hasRoundRectClip) { // TODO: avoid doing this repeatedly, stashing state pointer in program - const RoundRectClipState* state = mSnapshot->roundRectClipState; + const RoundRectClipState* state = writableSnapshot()->roundRectClipState; const Rect& innerRect = state->innerRect; glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, @@ -1725,7 +1715,8 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, bool dirty = right - left > 0.0f && bottom - top > 0.0f; const Matrix4& transformMatrix = ignoreTransform ? Matrix4::identity() : *currentTransform(); - mCaches.currentProgram->set(mSnapshot->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset); + mCaches.currentProgram->set(writableSnapshot()->getOrthoMatrix(), + mModelViewMatrix, transformMatrix, offset); if (dirty && mTrackDirtyRegions) { if (!ignoreTransform) { dirtyLayer(left, top, right, bottom, *currentTransform()); @@ -1748,7 +1739,7 @@ void OpenGLRenderer::setupDrawPureColorUniforms() { } void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform) { - if (shader == NULL) { + if (shader == nullptr) { return; } @@ -1766,7 +1757,7 @@ void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignore } void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { - if (NULL == filter) { + if (nullptr == filter) { return; } @@ -1814,7 +1805,7 @@ void OpenGLRenderer::setupDrawTextGammaUniforms() { void OpenGLRenderer::setupDrawSimpleMesh() { bool force = mCaches.bindMeshBuffer(); - mCaches.bindPositionVertexPointer(force, 0); + mCaches.bindPositionVertexPointer(force, nullptr); mCaches.unbindIndicesBuffer(); } @@ -1903,39 +1894,39 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { // Drawing /////////////////////////////////////////////////////////////////////////////// -status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { - status_t status; +void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (renderNode && renderNode->isRenderable()) { // compute 3d ordering renderNode->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { - status = startFrame(); + startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); renderNode->replay(replayStruct, 0); - return status | replayStruct.mDrawGlStatus; + return; } // Don't avoid overdraw when visualizing, since that makes it harder to // debug where it's coming from, and when the problem occurs. bool avoidOverdraw = !mCaches.debugOverdraw; - DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw); + DeferredDisplayList deferredList(*mState.currentClipRect(), avoidOverdraw); DeferStateStruct deferStruct(deferredList, *this, replayFlags); renderNode->defer(deferStruct, 0); flushLayers(); - status = startFrame(); + startFrame(); - return deferredList.flush(*this, dirty) | status; + deferredList.flush(*this, dirty); + } else { + // Even if there is no drawing command(Ex: invisible), + // it still needs startFrame to clear buffer and start tiling. + startFrame(); } - - // Even if there is no drawing command(Ex: invisible), - // it still needs startFrame to clear buffer and start tiling. - return startFrame(); } -void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) { +void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, + const SkPaint* paint) { float x = left; float y = top; @@ -1955,7 +1946,7 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co // No need to check for a UV mapper on the texture object, only ARGB_8888 // bitmaps get packed in the atlas drawAlpha8TextureMesh(x, y, x + texture->width, y + texture->height, texture->id, - paint, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, + paint, (GLvoid*) nullptr, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform); } @@ -1964,12 +1955,12 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); @@ -1990,17 +1981,17 @@ status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* kModelViewMode_Translate, false); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { @@ -2009,12 +2000,12 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); @@ -2027,13 +2018,13 @@ status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* p drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { - if (!vertices || currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; + if (!vertices || mState.currentlyIgnored()) { + return; } // TODO: use quickReject on bounds from vertices @@ -2046,17 +2037,15 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i const uint32_t count = meshWidth * meshHeight * 6; - Vector<ColorTextureVertex> mesh; // TODO: use C++11 unique_ptr - mesh.setCapacity(count); - ColorTextureVertex* vertex = mesh.editArray(); + std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[count]); + ColorTextureVertex* vertex = &mesh[0]; - bool cleanupColors = false; + std::unique_ptr<int[]> tempColors; if (!colors) { uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1); - int* newColors = new int[colorsCount]; - memset(newColors, 0xff, colorsCount * sizeof(int)); - colors = newColors; - cleanupColors = true; + tempColors.reset(new int[colorsCount]); + memset(tempColors.get(), 0xff, colorsCount * sizeof(int)); + colors = tempColors.get(); } mCaches.activeTexture(0); @@ -2099,15 +2088,13 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i } if (quickRejectSetupScissor(left, top, right, bottom)) { - if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } if (!texture) { texture = mCaches.textureCache.get(bitmap); if (!texture) { - if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } } const AutoTexture autoCleanup(texture); @@ -2145,22 +2132,20 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i glDisableVertexAttribArray(slot); } - if (cleanupColors) delete[] colors; - - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float width = texture->width; @@ -2234,33 +2219,33 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap); const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(), right - left, bottom - top, patch); - return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); + drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } if (CC_LIKELY(mesh && mesh->verticesCount > 0)) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2302,7 +2287,7 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2310,11 +2295,11 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2324,15 +2309,15 @@ status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* texture->blend, &vertices[0].x, &vertices[0].u, GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, +void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) { // not missing call to quickReject/dirtyLayer, always done at a higher level if (!vertexBuffer.getVertexCount()) { // no vertices to draw - return DrawGlInfo::kStatusDone; + return; } Rect bounds(vertexBuffer.getBounds()); @@ -2345,7 +2330,7 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, setupDraw(); setupDrawNoTexture(); if (isAA) setupDrawVertexAlpha((displayFlags & kVertexBuffer_ShadowInterp)); - setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); + setupDrawColor(color, ((color >> 24) & 0xFF) * writableSnapshot()->alpha); setupDrawColorFilter(getColorFilter(paint)); setupDrawShader(getShader(paint)); setupDrawBlending(paint, isAA); @@ -2376,21 +2361,23 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount()); } else if (mode == VertexBuffer::kOnePolyRingShadow) { mCaches.bindShadowIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, + GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kTwoPolyRingShadow) { mCaches.bindShadowIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, + GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kIndices) { mCaches.unbindIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), GL_UNSIGNED_SHORT, - vertexBuffer.getIndices()); + glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), + GL_UNSIGNED_SHORT, vertexBuffer.getIndices()); } if (isAA) { glDisableVertexAttribArray(alphaSlot); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2402,11 +2389,11 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, * * Doesn't yet support joins, caps, or path effects. */ -status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { +void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { VertexBuffer vertexBuffer; // TODO: try clipping large paths to viewport PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer); - return drawVertexBuffer(vertexBuffer, paint); + drawVertexBuffer(vertexBuffer, paint); } /** @@ -2420,8 +2407,8 @@ status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce * memory transfer by removing need for degenerate vertices. */ -status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 4) return; count &= ~0x3; // round down to nearest four @@ -2430,15 +2417,15 @@ status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); } -status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 2) return; count &= ~0x1; // round down to nearest two @@ -2447,18 +2434,20 @@ status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPain const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); + + mDirty = true; } -status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { +void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); SkPaint paint; @@ -2467,12 +2456,12 @@ status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, +void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint) { - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = left + texture->left - texture->offset; @@ -2480,89 +2469,89 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex drawPathTexture(texture, x, y, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRoundRect( right - left, bottom - top, rx, ry, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( + *currentTransform(), *p, right - left, bottom - top, rx, ry); + drawVertexBuffer(left, top, *vertexBuffer, p); } - - const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( - *currentTransform(), *p, right - left, bottom - top, rx, ry); - return drawVertexBuffer(left, top, *vertexBuffer, p); } -status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { - if (currentSnapshot()->isIgnored() +void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { + if (mState.currentlyIgnored() || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getCircle(radius, p); - return drawShape(x - radius, y - radius, texture, p); - } - - SkPath path; - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + drawShape(x - radius, y - radius, texture, p); } else { - path.addCircle(x, y, radius); + SkPath path; + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + } else { + path.addCircle(x, y, radius); + } + drawConvexPath(path, p); } - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom, +void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getOval(right - left, bottom - top, p); - return drawShape(left, top, texture, p); - } - - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addOval(rect); + drawConvexPath(path, p); } - path.addOval(rect); - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom, +void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180) - if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || useCenter) { + if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != nullptr || useCenter) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getArc(right - left, bottom - top, startAngle, sweepAngle, useCenter, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + return; } - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); @@ -2576,46 +2565,47 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto if (useCenter) { path.close(); } - return drawConvexPath(path, p); + drawConvexPath(path, p); } // See SkPaintDefaults.h #define SkPaintDefaults_MiterLimit SkIntToScalar(4) -status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } if (p->getStyle() != SkPaint::kFill_Style) { // only fill style is supported by drawConvexPath, since others have to handle joins - if (p->getPathEffect() != 0 || p->getStrokeJoin() != SkPaint::kMiter_Join || + if (p->getPathEffect() != nullptr || p->getStrokeJoin() != SkPaint::kMiter_Join || p->getStrokeMiter() != SkPaintDefaults_MiterLimit) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRect(right - left, bottom - top, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addRect(rect); + drawConvexPath(path, p); } + } else { + if (p->isAntiAlias() && !currentTransform()->isSimple()) { + SkPath path; + path.addRect(left, top, right, bottom); + drawConvexPath(path, p); + } else { + drawColorRect(left, top, right, bottom, p); - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + mDirty = true; } - path.addRect(rect); - return drawConvexPath(path, p); - } - - if (p->isAntiAlias() && !currentTransform()->isSimple()) { - SkPath path; - path.addRect(left, top, right, bottom); - return drawConvexPath(path, p); - } else { - drawColorRect(left, top, right, bottom, p); - return DrawGlInfo::kStatusDrew; } } @@ -2642,7 +2632,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, const float sx = x - shadow->left + textShadow.dx; const float sy = y - shadow->top + textShadow.dy; - const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * mSnapshot->alpha; + const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * writableSnapshot()->alpha; if (getShader(paint)) { textShadow.color = SK_ColorWHITE; } @@ -2660,25 +2650,25 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } bool OpenGLRenderer::canSkipText(const SkPaint* paint) const { - float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * mSnapshot->alpha; + float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha; return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; } -status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // NOTE: Skia does not support perspective transform on drawPosText yet if (!currentTransform()->isSimple()) { - return DrawGlInfo::kStatusDone; + return; } mCaches.enableScissor(); @@ -2710,14 +2700,14 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } fontRenderer.setTextureFiltering(linearFilter); - const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip(); + const Rect* clip = pureTranslate ? writableSnapshot()->clipRect : &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); TextSetupFunctor functor(this, x, y, pureTranslate, alpha, mode, paint); if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &bounds : NULL, &functor)) { + positions, hasActiveLayer ? &bounds : nullptr, &functor)) { if (hasActiveLayer) { if (!pureTranslate) { currentTransform()->mapRect(bounds); @@ -2726,7 +2716,7 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const { @@ -2750,16 +2740,79 @@ bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outM return true; } -status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, +int OpenGLRenderer::getSaveCount() const { + return mState.getSaveCount(); +} + +int OpenGLRenderer::save(int flags) { + return mState.save(flags); +} + +void OpenGLRenderer::restore() { + return mState.restore(); +} + +void OpenGLRenderer::restoreToCount(int saveCount) { + return mState.restoreToCount(saveCount); +} + +void OpenGLRenderer::translate(float dx, float dy, float dz) { + return mState.translate(dx, dy, dz); +} + +void OpenGLRenderer::rotate(float degrees) { + return mState.rotate(degrees); +} + +void OpenGLRenderer::scale(float sx, float sy) { + return mState.scale(sx, sy); +} + +void OpenGLRenderer::skew(float sx, float sy) { + return mState.skew(sx, sy); +} + +void OpenGLRenderer::setMatrix(const Matrix4& matrix) { + mState.setMatrix(matrix); +} + +void OpenGLRenderer::concatMatrix(const Matrix4& matrix) { + mState.concatMatrix(matrix); +} + +bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { + return mState.clipRect(left, top, right, bottom, op); +} + +bool OpenGLRenderer::clipPath(const SkPath* path, SkRegion::Op op) { + return mState.clipPath(path, op); +} + +bool OpenGLRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { + return mState.clipRegion(region, op); +} + +void OpenGLRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { + mState.setClippingOutline(allocator, outline); +} + +void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority) { + mState.setClippingRoundRect(allocator, rect, radius, highPriority); +} + + + +void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { if (drawOpMode == kDrawOpMode_Immediate) { // The checks for corner-case ignorable text and quick rejection is only done for immediate // drawing as ops from DeferredDisplayList are already filtered for these - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) || + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) || quickRejectSetupScissor(bounds)) { - return DrawGlInfo::kStatusDone; + return; } } @@ -2807,7 +2860,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f fontRenderer.setTextureFiltering(linearFilter); // TODO: Implement better clipping for scaled/rotated text - const Rect* clip = !pureTranslate ? NULL : currentClipRect(); + const Rect* clip = !pureTranslate ? nullptr : mState.currentClipRect(); Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); bool status; @@ -2819,10 +2872,10 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f SkPaint paintCopy(*paint); paintCopy.setTextAlign(SkPaint::kLeft_Align); status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); + positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } else { status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); + positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } if ((status || drawOpMode != kDrawOpMode_Immediate) && hasActiveLayer) { @@ -2834,13 +2887,13 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f drawTextDecorations(totalAdvance, oldX, oldY, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics @@ -2855,45 +2908,44 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co getAlphaAndMode(paint, &alpha, &mode); TextSetupFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint); - const Rect* clip = &mSnapshot->getLocalClip(); + const Rect* clip = &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path, - hOffset, vOffset, hasActiveLayer ? &bounds : NULL, &functor)) { + hOffset, vOffset, hasActiveLayer ? &bounds : nullptr, &functor)) { if (hasActiveLayer) { currentTransform()->mapRect(bounds); dirtyLayerUnchecked(bounds, getRegion()); } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { + if (mState.currentlyIgnored()) return; mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.get(path, paint); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = texture->left - texture->offset; const float y = texture->top - texture->offset; drawPathTexture(texture, x, y, paint); - - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { +void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { if (!layer) { - return DrawGlInfo::kStatusDone; + return; } - mat4* transform = NULL; + mat4* transform = nullptr; if (layer->isTextureLayer()) { transform = &layer->getTransform(); if (!transform->isIdentity()) { @@ -2903,14 +2955,15 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } bool clipRequired = false; - const bool rejected = calculateQuickRejectForScissor(x, y, - x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, NULL, false); + const bool rejected = mState.calculateQuickRejectForScissor( + x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), + &clipRequired, nullptr, false); if (rejected) { if (transform && !transform->isIdentity()) { restore(); } - return DrawGlInfo::kStatusDone; + return; } EVENT_LOGD("drawLayer," RECT_STRING ", clipRequired %d", x, y, @@ -2958,7 +3011,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { setupDrawMeshIndices(&mesh[0].x, &mesh[0].u); DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, - glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL)); + glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, nullptr)); elementsCount -= drawCount; // Though there are 4 vertices in a quad, we use 6 indices per @@ -2985,53 +3038,16 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { restore(); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// // Draw filters /////////////////////////////////////////////////////////////////////////////// - -void OpenGLRenderer::resetPaintFilter() { - // when clearing the PaintFilter, the masks should also be cleared for simple DrawModifier - // comparison, see MergingDrawBatch::canMergeWith - mDrawModifiers.mHasDrawFilter = false; - mDrawModifiers.mPaintFilterClearBits = 0; - mDrawModifiers.mPaintFilterSetBits = 0; -} - -void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) { - // TODO: don't bother with boolean, it's redundant with clear/set bits - mDrawModifiers.mHasDrawFilter = true; - mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags; - mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags; -} - -const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) { - // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp - // to avoid clobbering 0x02 paint flag - - // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. - static const uint32_t sFilterBitmapFlag = 0x02; - - if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) { - return paint; - } - - const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits; - const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits; - - const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits; - mFilteredPaint = *paint; - mFilteredPaint.setFlags(flags); - - // check if paint filter trying to override bitmap filter - if ((clearBits | setBits) & sFilterBitmapFlag) { - mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag - ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); - } - - return &mFilteredPaint; +void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) { + // We should never get here since we apply the draw filter when stashing + // the paints in the DisplayList. + LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters"); } /////////////////////////////////////////////////////////////////////////////// @@ -3069,7 +3085,7 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } @@ -3124,17 +3140,17 @@ void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, } } -status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { + if (mState.currentlyIgnored()) { + return; } - return drawColorRects(rects, count, paint, false, true, true); + drawColorRects(rects, count, paint, false, true, true); } -status_t OpenGLRenderer::drawShadow(float casterAlpha, +void OpenGLRenderer::drawShadow(float casterAlpha, const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; // TODO: use quickRejectWithScissor. For now, always force enable scissor. mCaches.enableScissor(); @@ -3161,13 +3177,13 @@ status_t OpenGLRenderer::drawShadow(float casterAlpha, drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp); } - return DrawGlInfo::kStatusDrew; + mDirty=true; } -status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, +void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, bool ignoreTransform, bool dirty, bool clip) { if (count == 0) { - return DrawGlInfo::kStatusDone; + return; } int color = paint->getColor(); @@ -3202,7 +3218,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP } if (clip && quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } setupDraw(); @@ -3225,7 +3241,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP issueIndexedQuadDraw(&mesh[0], count / 4); - return DrawGlInfo::kStatusDrew; + mDirty = true; } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, @@ -3257,7 +3273,7 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b Texture* texture, const SkPaint* paint) { texture->setWrap(GL_CLAMP_TO_EDGE, true); - GLvoid* vertices = (GLvoid*) NULL; + GLvoid* vertices = (GLvoid*) nullptr; GLvoid* texCoords = (GLvoid*) gMeshTextureOffset; if (texture->uvMapper) { @@ -3340,7 +3356,7 @@ void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawMeshIndices(vertices, texCoords, vbo); - glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL); + glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, nullptr); } void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom, @@ -3348,14 +3364,14 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) { - int color = paint != NULL ? paint->getColor() : 0; + int color = paint != nullptr ? paint->getColor() : 0; int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); setupDraw(); setupDrawWithTexture(true); - if (paint != NULL) { + if (paint != nullptr) { setupDrawAlpha8Color(color, alpha); } setupDrawColorFilter(getColorFilter(paint)); @@ -3376,7 +3392,7 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, bool swapSrcDst) { - if (mSnapshot->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) { + if (writableSnapshot()->roundRectClipState != nullptr /*&& !mSkipOutlineClip*/) { blend = true; mDescription.hasRoundRectClip = true; } @@ -3426,7 +3442,7 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool OpenGLRenderer::useProgram(Program* program) { if (!program->isInUse()) { - if (mCaches.currentProgram != NULL) mCaches.currentProgram->remove(); + if (mCaches.currentProgram != nullptr) mCaches.currentProgram->remove(); program->use(); mCaches.currentProgram = program; return false; @@ -3442,7 +3458,8 @@ void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, flo TextureVertex::setUV(v++, u2, v2); } -void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const { +void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, + SkXfermode::Mode* mode) const { getAlphaAndModeDirect(paint, alpha, mode); if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) { // if drawing a layer, ignore the paint's alpha diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 5eee2e2318af..9de4149687ae 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -38,6 +38,7 @@ #include <androidfw/ResourceTypes.h> +#include "CanvasState.h" #include "Debug.h" #include "Extensions.h" #include "Matrix.h" @@ -45,11 +46,9 @@ #include "Rect.h" #include "Renderer.h" #include "Snapshot.h" -#include "StatefulBaseRenderer.h" #include "UvMapper.h" #include "Vertex.h" #include "Caches.h" -#include "CanvasProperty.h" class SkShader; @@ -63,20 +62,14 @@ class TextSetupFunctor; class VertexBuffer; struct DrawModifiers { - DrawModifiers() { - reset(); - } + DrawModifiers() + : mOverrideLayerAlpha(0.0f) {} void reset() { - memset(this, 0, sizeof(DrawModifiers)); + mOverrideLayerAlpha = 0.0f; } float mOverrideLayerAlpha; - - // Draw filters - bool mHasDrawFilter; - int mPaintFilterClearBits; - int mPaintFilterSetBits; }; enum StateDeferFlags { @@ -123,7 +116,7 @@ enum ModelViewMode { /** * OpenGL Renderer implementation. */ -class OpenGLRenderer : public StatefulBaseRenderer { +class OpenGLRenderer : public Renderer, public CanvasStateClient { public: OpenGLRenderer(RenderState& renderState); virtual ~OpenGLRenderer(); @@ -132,11 +125,14 @@ public: void initLight(const Vector3& lightCenter, float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); - virtual void onViewportInitialized(); - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, float bottom, + bool opaque) override; + virtual void prepare(bool opaque) override { + prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque); + } + virtual bool finish() override; - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + virtual void callDrawGLFunction(Functor* functor, Rect& dirty) override; void pushLayerUpdate(Layer* layer); void cancelLayerUpdate(Layer* layer); @@ -144,8 +140,8 @@ public: void markLayersAsBuildLayers(); virtual int saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags) { - return saveLayer(left, top, right, bottom, paint, flags, NULL); + const SkPaint* paint, int flags) override { + return saveLayer(left, top, right, bottom, paint, flags, nullptr); } // Specialized saveLayer implementation, which will pass the convexMask to an FBO layer, if @@ -156,56 +152,55 @@ public: int saveLayerDeferred(float left, float top, float right, float bottom, const SkPaint* paint, int flags); - virtual status_t drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1); - virtual status_t drawLayer(Layer* layer, float x, float y); - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); - status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, + virtual void drawRenderNode(RenderNode* displayList, Rect& dirty, + int32_t replayFlags = 1) override; + virtual void drawLayer(Layer* layer, float x, float y); + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) override; + void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint); - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, const SkPaint* paint); - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, - const float* vertices, const int* colors, const SkPaint* paint); - status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, + float dstRight, float dstBottom, const SkPaint* paint) override; + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) override; + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint) override; + void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint); - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, - float left, float top, float right, float bottom, const SkPaint* paint); - status_t drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + float left, float top, float right, float bottom, const SkPaint* paint) override; + void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawColor(int color, SkXfermode::Mode mode); - virtual status_t drawRect(float left, float top, float right, float bottom, - const SkPaint* paint); - virtual status_t drawRoundRect(float left, float top, float right, float bottom, - float rx, float ry, const SkPaint* paint); - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint); - virtual status_t drawOval(float left, float top, float right, float bottom, - const SkPaint* paint); - virtual status_t drawArc(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint); - virtual status_t drawPath(const SkPath* path, const SkPaint* paint); - virtual status_t drawLines(const float* points, int count, const SkPaint* paint); - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint); - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, - float hOffset, float vOffset, const SkPaint* paint); - virtual status_t drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint); - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawColor(int color, SkXfermode::Mode mode) override; + virtual void drawRect(float left, float top, float right, float bottom, + const SkPaint* paint) override; + virtual void drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, const SkPaint* paint) override; + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) override; + virtual void drawOval(float left, float top, float right, float bottom, + const SkPaint* paint) override; + virtual void drawArc(float left, float top, float right, float bottom, + float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) override; + virtual void drawPath(const SkPath* path, const SkPaint* paint) override; + virtual void drawLines(const float* points, int count, const SkPaint* paint) override; + virtual void drawPoints(const float* points, int count, const SkPaint* paint) override; + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + float hOffset, float vOffset, const SkPaint* paint) override; + virtual void drawPosText(const char* text, int bytesCount, int count, + const float* positions, const SkPaint* paint) override; + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, - DrawOpMode drawOpMode = kDrawOpMode_Immediate); - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); + DrawOpMode drawOpMode = kDrawOpMode_Immediate) override; + virtual void drawRects(const float* rects, int count, const SkPaint* paint) override; - status_t drawShadow(float casterAlpha, - const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer); + void drawShadow(float casterAlpha, + const VertexBuffer* ambientShadowVertexBuffer, + const VertexBuffer* spotShadowVertexBuffer); - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + virtual void setDrawFilter(SkDrawFilter* filter) override; // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer) void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; } - const SkPaint* filterPaint(const SkPaint* paint); - /** * Store the current display state (most importantly, the current clip and transform), and * additionally map the state's bounds from local to window coordinates. @@ -228,20 +223,16 @@ public: } // simple rect clip - bool isCurrentClipSimple() { - return mSnapshot->clipRegion->isEmpty(); - } + bool isCurrentClipSimple() { return mState.isCurrentClipSimple(); } - int getViewportWidth() { return currentSnapshot()->getViewportWidth(); } - int getViewportHeight() { return currentSnapshot()->getViewportHeight(); } + int getViewportWidth() { return mState.getViewportWidth(); } + int getViewportHeight() { return mState.getViewportHeight(); } /** * Scales the alpha on the current snapshot. This alpha value will be modulated * with other alpha values when drawing primitives. */ - void scaleAlpha(float alpha) { - mSnapshot->alpha *= alpha; - } + void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); } /** * Inserts a named event marker in the stream of GL commands. @@ -275,7 +266,8 @@ public: * @param alpha Where to store the resulting alpha * @param mode Where to store the resulting xfermode */ - static inline void getAlphaAndModeDirect(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) { + static inline void getAlphaAndModeDirect(const SkPaint* paint, int* alpha, + SkXfermode::Mode* mode) { *mode = getXfermodeDirect(paint); *alpha = getAlphaDirect(paint); } @@ -312,7 +304,7 @@ public: } static inline bool hasTextShadow(const SkPaint* paint) { - return getTextShadow(paint, NULL); + return getTextShadow(paint, nullptr); } /** @@ -334,18 +326,74 @@ public: drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true); if (stencilWasEnabled) mCaches.stencil.enableTest(); + mDirty = true; } #endif - const Vector3& getLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } + const Vector3& getLightCenter() const { return mState.currentLightCenter(); } float getLightRadius() const { return mLightRadius; } uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; } uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; } + /////////////////////////////////////////////////////////////////// + /// State manipulation + + virtual void setViewport(int width, int height) override { mState.setViewport(width, height); } + + virtual int getSaveCount() const override; + virtual int save(int flags) override; + virtual void restore() override; + virtual void restoreToCount(int saveCount) override; + + virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } + virtual void setMatrix(const SkMatrix& matrix) override { mState.setMatrix(matrix); } + virtual void concatMatrix(const SkMatrix& matrix) override { mState.concatMatrix(matrix); } + + virtual void translate(float dx, float dy, float dz = 0.0f) override; + virtual void rotate(float degrees) override; + virtual void scale(float sx, float sy) override; + virtual void skew(float sx, float sy) override; + + void setMatrix(const Matrix4& matrix); // internal only convenience method + void concatMatrix(const Matrix4& matrix); // internal only convenience method + + virtual const Rect& getLocalClipBounds() const override { return mState.getLocalClipBounds(); } + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } + virtual bool quickRejectConservative(float left, float top, + float right, float bottom) const override { + return mState.quickRejectConservative(left, top, right, bottom); + } + + virtual bool clipRect(float left, float top, + float right, float bottom, SkRegion::Op op) override; + virtual bool clipPath(const SkPath* path, SkRegion::Op op) override; + virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override; + + /** + * Does not support different clipping Ops (that is, every call to setClippingOutline is + * effectively using SkRegion::kReplaceOp) + * + * The clipping outline is independent from the regular clip. + */ + void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority = true); + + inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); } + inline const mat4* currentTransform() const { return mState.currentTransform(); } + + /////////////////////////////////////////////////////////////////// + /// CanvasStateClient interface + + virtual void onViewportInitialized() override; + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override; + virtual GLuint onGetTargetFbo() const override { return 0; } + SkPath* allocPathForFrame() { - SkPath* path = new SkPath(); - mTempPaths.push_back(path); - return path; + std::unique_ptr<SkPath> path(new SkPath()); + SkPath* returnPath = path.get(); + mTempPaths.push_back(std::move(path)); + return returnPath; } protected: @@ -359,12 +407,12 @@ protected: * Indicates the start of rendering. This method will setup the * initial OpenGL state (viewport, clearing the buffer, etc.) */ - status_t startFrame(); + void startFrame(); /** * Clears the underlying surface if needed. */ - virtual status_t clear(float left, float top, float right, float bottom, bool opaque); + virtual void clear(float left, float top, float right, float bottom, bool opaque); /** * Call this method after updating a layer during a drawing pass. @@ -385,8 +433,8 @@ protected: void attachStencilBufferToLayer(Layer* layer); bool quickRejectSetupScissor(float left, float top, float right, float bottom, - const SkPaint* paint = NULL); - bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = NULL) { + const SkPaint* paint = nullptr); + bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = nullptr) { return quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom, paint); } @@ -411,22 +459,16 @@ protected: * Returns the region of the current layer. */ virtual Region* getRegion() const { - return mSnapshot->region; + return mState.currentRegion(); } /** * Indicates whether rendering is currently targeted at a layer. */ virtual bool hasLayer() const { - return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region; + return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion(); } - /** - * Returns the name of the FBO this renderer is rendering into. - */ - virtual GLuint getTargetFbo() const { - return 0; - } /** * Renders the specified layer as a textured quad. @@ -459,7 +501,7 @@ protected: * null then null is returned. */ static inline SkColorFilter* getColorFilter(const SkPaint* paint) { - return paint ? paint->getColorFilter() : NULL; + return paint ? paint->getColorFilter() : nullptr; } /** @@ -467,7 +509,7 @@ protected: * null then null is returned. */ static inline const SkShader* getShader(const SkPaint* paint) { - return paint ? paint->getShader() : NULL; + return paint ? paint->getShader() : nullptr; } /** @@ -479,6 +521,8 @@ protected: inline RenderState& renderState() { return mRenderState; } + CanvasState mState; + private: /** * Discards the content of the framebuffer if supported by the driver. @@ -514,8 +558,6 @@ private: */ void endTiling(); - void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored); - /** * Sets the clipping rectangle using glScissor. The clip is defined by * the current snapshot's clipRect member. @@ -629,7 +671,7 @@ private: * @param dirty True if calling this method should dirty the current layer * @param clip True if the rects should be clipped, false otherwise */ - status_t drawColorRects(const float* rects, int count, const SkPaint* paint, + void drawColorRects(const float* rects, int count, const SkPaint* paint, bool ignoreTransform = false, bool dirty = true, bool clip = true); /** @@ -643,7 +685,7 @@ private: * @param texture The texture reprsenting the shape * @param paint The paint to draw the shape with */ - status_t drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint); + void drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint); /** * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey @@ -663,15 +705,15 @@ private: * @param paint The paint to render with * @param flags flags with which to draw */ - status_t drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, + void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, const SkPaint* paint, int flags = 0); /** * Convenience for translating method */ - status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, + void drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint, int flags = 0) { - return drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags); + drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags); } /** @@ -680,7 +722,7 @@ private: * @param path The hull of the path to draw * @param paint The paint to render with */ - status_t drawConvexPath(const SkPath& path, const SkPaint* paint); + void drawConvexPath(const SkPath& path, const SkPaint* paint); /** * Draws a textured rectangle with the specified texture. The specified coordinates @@ -867,8 +909,8 @@ private: * space must be scaled up and translated to fill the quad provided in (l,t,r,b). These * transformations are stored in the modelView matrix and uploaded to the shader. * - * @param offset Set to true if the the matrix should be fudged (translated) slightly to disambiguate - * geometry pixel positioning. See Vertex::GeometryFudgeFactor(). + * @param offset Set to true if the the matrix should be fudged (translated) slightly to + * disambiguate geometry pixel positioning. See Vertex::GeometryFudgeFactor(). * * @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space, * currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil, @@ -894,7 +936,7 @@ private: void setupDrawTextureTransform(); void setupDrawTextureTransformUniforms(mat4& transform); void setupDrawTextGammaUniforms(); - void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords = NULL, GLuint vbo = 0); + void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords = nullptr, GLuint vbo = 0); void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, const GLvoid* colors); void setupDrawMeshIndices(const GLvoid* vertices, const GLvoid* texCoords, GLuint vbo = 0); void setupDrawIndexedVertices(GLvoid* vertices); @@ -931,9 +973,7 @@ private: /** * Should be invoked every time the glScissor is modified. */ - inline void dirtyClip() { - mDirtyClip = true; - } + inline void dirtyClip() { mState.setDirtyClip(true); } inline const UvMapper& getMapper(const Texture* texture) { return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper; @@ -946,6 +986,10 @@ private: */ Texture* getTexture(const SkBitmap* bitmap); + bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; } + inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); } + inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); } + /** * Model-view matrix used to position/size objects * @@ -985,7 +1029,7 @@ private: RenderState& mRenderState; // List of rectangles to clear after saveLayer() is invoked - Vector<Rect*> mLayers; + std::vector<Rect> mLayers; // List of layers to update at the beginning of a frame Vector< sp<Layer> > mLayerUpdates; @@ -1014,6 +1058,10 @@ private: bool mSkipOutlineClip; + // True if anything has been drawn since the last call to + // reportAndClearDirty() + bool mDirty; + // Lighting + shadows Vector3 mLightCenter; float mLightRadius; @@ -1021,7 +1069,7 @@ private: uint8_t mSpotShadowAlpha; // Paths kept alive for the duration of the frame - std::vector<SkPath*> mTempPaths; + std::vector<std::unique_ptr<SkPath>> mTempPaths; friend class Layer; friend class TextSetupFunctor; diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h index 6dacd5edd387..5e9b21312d79 100644 --- a/libs/hwui/Outline.h +++ b/libs/hwui/Outline.h @@ -95,7 +95,7 @@ public: } const SkPath* getPath() const { - if (mType == kOutlineType_None || mType == kOutlineType_Empty) return NULL; + if (mType == kOutlineType_None || mType == kOutlineType_Empty) return nullptr; return &mPath; } diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index 442e9ba616cf..442dc5b64793 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -32,11 +32,7 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -Patch::Patch(): vertices(NULL), verticesCount(0), indexCount(0), hasEmptyQuads(false) { -} - -Patch::~Patch() { - delete[] vertices; +Patch::Patch(): vertices(), verticesCount(0), indexCount(0), hasEmptyQuads(false) { } /////////////////////////////////////////////////////////////////////////////// @@ -55,7 +51,7 @@ TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeig TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeight, float width, float height, const UvMapper& mapper, const Res_png_9patch* patch) { - if (vertices) return vertices; + if (vertices) return vertices.get(); int8_t emptyQuads = 0; mColors = patch->getColors(); @@ -77,8 +73,8 @@ TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeig uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 4; if (maxVertices == 0) return NULL; - TextureVertex* tempVertices = new TextureVertex[maxVertices]; - TextureVertex* vertex = tempVertices; + vertices.reset(new TextureVertex[maxVertices]); + TextureVertex* vertex = vertices.get(); const int32_t* xDivs = patch->getXDivs(); const int32_t* yDivs = patch->getYDivs(); @@ -157,15 +153,13 @@ TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeig width, bitmapWidth, quadCount); } - if (verticesCount == maxVertices) { - vertices = tempVertices; - } else { - vertices = new TextureVertex[verticesCount]; - memcpy(vertices, tempVertices, verticesCount * sizeof(TextureVertex)); - delete[] tempVertices; + if (verticesCount != maxVertices) { + std::unique_ptr<TextureVertex[]> reducedVertices(new TextureVertex[verticesCount]); + memcpy(reducedVertices.get(), vertices.get(), verticesCount * sizeof(TextureVertex)); + vertices = std::move(reducedVertices); } - return vertices; + return vertices.get(); } void Patch::generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex, diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h index 1ba045d04528..ea8c8c23d523 100644 --- a/libs/hwui/Patch.h +++ b/libs/hwui/Patch.h @@ -27,11 +27,12 @@ #include "Rect.h" #include "UvMapper.h" -#include "Vertex.h" namespace android { namespace uirenderer { +struct TextureVertex; + /////////////////////////////////////////////////////////////////////////////// // 9-patch structures /////////////////////////////////////////////////////////////////////////////// @@ -39,14 +40,13 @@ namespace uirenderer { class Patch { public: Patch(); - ~Patch(); /** * Returns the size of this patch's mesh in bytes. */ uint32_t getSize() const; - TextureVertex* vertices; + std::unique_ptr<TextureVertex[]> vertices; uint32_t verticesCount; uint32_t indexCount; bool hasEmptyQuads; diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index 2f2debc89dd1..1920fcfeebc9 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -20,6 +20,7 @@ #include <utils/Log.h> #include "Caches.h" +#include "Patch.h" #include "PatchCache.h" #include "Properties.h" diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 9f2c9a59387b..4cb533841ee1 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -25,12 +25,13 @@ #include "AssetAtlas.h" #include "Debug.h" -#include "Patch.h" #include "utils/Pair.h" namespace android { namespace uirenderer { +class Patch; + /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// @@ -90,7 +91,7 @@ public: private: struct PatchDescription { - PatchDescription(): mPatch(NULL), mBitmapWidth(0), mBitmapHeight(0), + PatchDescription(): mPatch(nullptr), mBitmapWidth(0), mBitmapHeight(0), mPixelWidth(0), mPixelHeight(0) { } @@ -145,7 +146,7 @@ private: * to track available regions of memory in the VBO. */ struct BufferBlock { - BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(NULL) { + BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(nullptr) { } uint32_t offset; diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index bc34188f061c..ecd3712ce6eb 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -24,7 +24,6 @@ #include <utils/Vector.h> #include "Debug.h" -#include "Properties.h" #include "Texture.h" #include "utils/Macros.h" #include "utils/Pair.h" @@ -88,7 +87,7 @@ struct PathTexture: public Texture { } void clearTask() { - if (mTask != NULL) { + if (mTask != nullptr) { mTask.clear(); } } @@ -166,7 +165,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(PathDescription& path, PathTexture*& texture); + void operator()(PathDescription& path, PathTexture*& texture) override; /** * Clears the cache. This causes all textures to be deleted. @@ -293,7 +292,7 @@ private: PathProcessor(Caches& caches); ~PathProcessor() { } - virtual void onProcess(const sp<Task<SkBitmap*> >& task); + virtual void onProcess(const sp<Task<SkBitmap*> >& task) override; private: uint32_t mMaxTextureSize; diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp index 9f7dd5070b5b..ceec4fce005e 100644 --- a/libs/hwui/PathTessellator.cpp +++ b/libs/hwui/PathTessellator.cpp @@ -229,7 +229,6 @@ void getStrokeVerticesFromPerimeter(const PaintInfo& paintInfo, const Vector<Ver current->x - totalOffset.x, current->y - totalOffset.y); - last = current; current = next; lastNormal = nextNormal; } @@ -372,7 +371,6 @@ void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Ver current->y - totalOffset.y, maxAlpha); - last = current; current = next; lastNormal = nextNormal; } @@ -700,7 +698,6 @@ void getStrokeVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<V current->y - outerOffset.y, 0.0f); - last = current; current = next; lastNormal = nextNormal; } diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp index 5b642b993a2e..6c448f04fd24 100644 --- a/libs/hwui/PixelBuffer.cpp +++ b/libs/hwui/PixelBuffer.cpp @@ -34,7 +34,6 @@ namespace uirenderer { class CpuPixelBuffer: public PixelBuffer { public: CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); - ~CpuPixelBuffer(); uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); void unmap(); @@ -44,23 +43,19 @@ public: void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); private: - uint8_t* mBuffer; + std::unique_ptr<uint8_t[]> mBuffer; }; -CpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): - PixelBuffer(format, width, height) { - mBuffer = new uint8_t[width * height * formatSize(format)]; -} - -CpuPixelBuffer::~CpuPixelBuffer() { - delete[] mBuffer; +CpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height) + : PixelBuffer(format, width, height) + , mBuffer(new uint8_t[width * height * formatSize(format)]) { } uint8_t* CpuPixelBuffer::map(AccessMode mode) { if (mAccessMode == kAccessMode_None) { mAccessMode = mode; } - return mBuffer; + return mBuffer.get(); } void CpuPixelBuffer::unmap() { @@ -68,12 +63,12 @@ void CpuPixelBuffer::unmap() { } uint8_t* CpuPixelBuffer::getMappedPointer() const { - return mAccessMode == kAccessMode_None ? NULL : mBuffer; + return mAccessMode == kAccessMode_None ? nullptr : mBuffer.get(); } void CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, - mFormat, GL_UNSIGNED_BYTE, mBuffer + offset); + mFormat, GL_UNSIGNED_BYTE, &mBuffer[offset]); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index fc7d13410f5c..d05b331909e2 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -281,8 +281,6 @@ struct ProgramDescription { programid k = key(); PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32), uint32_t(k & 0xffffffff)); -#else - (void)message; #endif } diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 62835e01cb3a..6d3f0cbc1af3 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -417,11 +417,6 @@ ProgramCache::~ProgramCache() { void ProgramCache::clear() { PROGRAM_LOGD("Clearing program cache"); - - size_t count = mCache.size(); - for (size_t i = 0; i < count; i++) { - delete mCache.valueAt(i); - } mCache.clear(); } @@ -433,14 +428,14 @@ Program* ProgramCache::get(const ProgramDescription& description) { key = PROGRAM_KEY_TEXTURE; } - ssize_t index = mCache.indexOfKey(key); + auto iter = mCache.find(key); Program* program = NULL; - if (index < 0) { + if (iter == mCache.end()) { description.log("Could not find program"); program = generateProgram(description, key); - mCache.add(key, program); + mCache[key] = std::unique_ptr<Program>(program); } else { - program = mCache.valueAt(index); + program = iter->second.get(); } return program; } diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h index 38f6f99f8996..30fa0df8d75c 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -20,12 +20,12 @@ #include <utils/KeyedVector.h> #include <utils/Log.h> #include <utils/String8.h> +#include <map> #include <GLES2/gl2.h> #include "Debug.h" #include "Program.h" -#include "Properties.h" namespace android { namespace uirenderer { @@ -56,7 +56,7 @@ private: void printLongString(const String8& shader) const; - KeyedVector<programid, Program*> mCache; + std::map<programid, std::unique_ptr<Program>> mCache; const bool mHasES3; }; // class ProgramCache diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 7b9459a56fbf..a0312e1a52e0 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -255,7 +255,7 @@ enum DebugLevel { static inline DebugLevel readDebugLevel() { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_DEBUG, property, NULL) > 0) { + if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) { return (DebugLevel) atoi(property); } return kDebugDisabled; diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h index 13265a96b05c..b046b6fb8be9 100644 --- a/libs/hwui/Rect.h +++ b/libs/hwui/Rect.h @@ -248,7 +248,7 @@ public: bottom = fmaxf(bottom, y); } - void dump(const char* label = NULL) const { + void dump(const char* label = nullptr) const { ALOGD("%s[l=%f t=%f r=%f b=%f]", label ? label : "Rect", left, top, right, bottom); } diff --git a/libs/hwui/RenderBufferCache.h b/libs/hwui/RenderBufferCache.h index af8060fe2d21..6c668b09c40d 100644 --- a/libs/hwui/RenderBufferCache.h +++ b/libs/hwui/RenderBufferCache.h @@ -78,11 +78,11 @@ public: private: struct RenderBufferEntry { RenderBufferEntry(): - mBuffer(NULL), mWidth(0), mHeight(0) { + mBuffer(nullptr), mWidth(0), mHeight(0) { } RenderBufferEntry(GLenum format, const uint32_t width, const uint32_t height): - mBuffer(NULL), mFormat(format), mWidth(width), mHeight(height) { + mBuffer(nullptr), mFormat(format), mWidth(width), mHeight(height) { } RenderBufferEntry(RenderBuffer* buffer): diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index c99355672df1..ad38a1289fcb 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -32,6 +32,7 @@ #include "DisplayListLogBuffer.h" #include "LayerRenderer.h" #include "OpenGLRenderer.h" +#include "TreeInfo.h" #include "utils/MathUtils.h" #include "utils/TraceUtils.h" #include "renderthread/CanvasContext.h" @@ -869,7 +870,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { return; } - const bool drawLayer = (mLayer && (&renderer != mLayer->renderer)); + const bool drawLayer = (mLayer && (&renderer != mLayer->renderer.get())); // If we are updating the contents of mLayer, we don't want to apply any of // the RenderNode's properties to this issueOperations pass. Those will all // be applied when the layer is drawn, aka when this is true. diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 2ce7cb7f3034..bbe53ff29baf 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -33,13 +33,10 @@ #include <androidfw/ResourceTypes.h> #include "AnimatorManager.h" -#include "DamageAccumulator.h" #include "Debug.h" #include "Matrix.h" -#include "DeferredDisplayList.h" #include "DisplayList.h" #include "RenderProperties.h" -#include "TreeInfo.h" class SkBitmap; class SkPaint; @@ -61,6 +58,7 @@ class SaveLayerOp; class SaveOp; class RestoreToCountOp; class DrawRenderNodeOp; +class TreeInfo; /** * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 31c4f2203991..f0e22d6508b0 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -26,8 +26,8 @@ #include <SkCamera.h> #include <SkMatrix.h> #include <SkRegion.h> +#include <SkXfermode.h> -#include "Animator.h" #include "Rect.h" #include "RevealClip.h" #include "Outline.h" @@ -188,7 +188,7 @@ public: if (matrix) { mStaticMatrix = new SkMatrix(*matrix); } else { - mStaticMatrix = NULL; + mStaticMatrix = nullptr; } return true; } @@ -203,7 +203,7 @@ public: if (matrix) { mAnimationMatrix = new SkMatrix(*matrix); } else { - mAnimationMatrix = NULL; + mAnimationMatrix = nullptr; } return true; } @@ -571,7 +571,7 @@ public: bool hasShadow() const { return getZ() > 0.0f - && getOutline().getPath() != NULL + && getOutline().getPath() != nullptr && getOutline().getAlpha() != 0.0f; } diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h index 1ecfb1cf7c6c..629fe0d10b91 100644 --- a/libs/hwui/RenderState.h +++ b/libs/hwui/RenderState.h @@ -20,6 +20,8 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <utils/Mutex.h> +#include <utils/Functor.h> +#include <utils/RefBase.h> #include <private/hwui/DrawGlInfo.h> @@ -30,6 +32,9 @@ namespace android { namespace uirenderer { +class Caches; +class Layer; + namespace renderthread { class CanvasContext; class RenderThread; diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index 3159d1e67bdb..ee44d7a6aadb 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -20,11 +20,12 @@ #include <SkColorFilter.h> #include <SkPaint.h> #include <SkRegion.h> - #include <utils/String8.h> #include "AssetAtlas.h" +class SkDrawFilter; + namespace android { class Functor; @@ -78,13 +79,13 @@ public: // TODO: move to a method on android:Paint static inline bool paintWillNotDrawText(const SkPaint& paint) { return paint.getAlpha() == 0 - && paint.getLooper() == NULL + && paint.getLooper() == nullptr && !paint.getColorFilter() && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; } static bool isBlendedColorFilter(const SkColorFilter* filter) { - if (filter == NULL) { + if (filter == nullptr) { return false; } return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; @@ -111,7 +112,7 @@ public: * and will not be cleared. If false, the target surface * will be cleared */ - virtual status_t prepare(bool opaque) = 0; + virtual void prepare(bool opaque) = 0; /** * Prepares the renderer to draw a frame. This method must be invoked @@ -127,14 +128,16 @@ public: * and will not be cleared. If false, the target surface * will be cleared in the specified dirty rectangle */ - virtual status_t prepareDirty(float left, float top, float right, float bottom, + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque) = 0; /** * Indicates the end of a frame. This method must be invoked whenever * the caller is done rendering a frame. + * Returns true if any drawing was done during the frame (the output + * has changed / is "dirty" and should be displayed to the user). */ - virtual void finish() = 0; + virtual bool finish() = 0; // ---------------------------------------------------------------------------- // Canvas state operations @@ -173,58 +176,57 @@ public: virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0; virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0; - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter() = 0; - virtual void setupPaintFilter(int clearBits, int setBits) = 0; + // Misc + virtual void setDrawFilter(SkDrawFilter* filter) = 0; // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0; + virtual void drawColor(int color, SkXfermode::Mode mode) = 0; // Bitmap-based - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0; - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0; + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) = 0; - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0; - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0; + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) = 0; - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) = 0; // Shapes - virtual status_t drawRect(float left, float top, float right, float bottom, + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) = 0; - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0; - virtual status_t drawRoundRect(float left, float top, float right, float bottom, + virtual void drawRects(const float* rects, int count, const SkPaint* paint) = 0; + virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint) = 0; - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0; - virtual status_t drawOval(float left, float top, float right, float bottom, + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) = 0; + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint* paint) = 0; - virtual status_t drawArc(float left, float top, float right, float bottom, + virtual void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0; - virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0; - virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0; - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0; + virtual void drawPath(const SkPath* path, const SkPaint* paint) = 0; + virtual void drawLines(const float* points, int count, const SkPaint* paint) = 0; + virtual void drawPoints(const float* points, int count, const SkPaint* paint) = 0; // Text - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0; - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) = 0; - virtual status_t drawPosText(const char* text, int bytesCount, int count, + virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) = 0; // ---------------------------------------------------------------------------- // Canvas draw operations - special // ---------------------------------------------------------------------------- - virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, + virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) = 0; // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty) = 0; + virtual void callDrawGLFunction(Functor* functor, Rect& dirty) = 0; }; // class Renderer }; // namespace uirenderer diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 31bd6376d5d7..8a48a6e6c04c 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -22,10 +22,8 @@ namespace android { -#ifdef USE_OPENGL_RENDERER using namespace uirenderer; ANDROID_SINGLETON_STATIC_INSTANCE(ResourceCache); -#endif namespace uirenderer { diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index f12f2a427d16..a252f6ce1413 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -20,17 +20,18 @@ #include <cutils/compiler.h> #include <SkBitmap.h> +#include <SkPath.h> #include <utils/KeyedVector.h> #include <utils/Singleton.h> #include <androidfw/ResourceTypes.h> -#include "Layer.h" - namespace android { namespace uirenderer { +class Layer; + /** * Type of Resource being cached */ diff --git a/libs/hwui/RevealClip.h b/libs/hwui/RevealClip.h index a9600f18f9bf..0084a8edccfc 100644 --- a/libs/hwui/RevealClip.h +++ b/libs/hwui/RevealClip.h @@ -54,7 +54,7 @@ public: float getRadius() const { return mRadius; } const SkPath* getPath() const { - if (!mShouldClip) return NULL; + if (!mShouldClip) return nullptr; return &mPath; } diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h index 8f19b5c481c7..16ad91dd7b4e 100644 --- a/libs/hwui/ShadowTessellator.h +++ b/libs/hwui/ShadowTessellator.h @@ -18,14 +18,16 @@ #ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H #define ANDROID_HWUI_SHADOW_TESSELLATOR_H +#include <SkPath.h> + #include "Debug.h" #include "Matrix.h" -#include "OpenGLRenderer.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + // All SHADOW_* are used to define all the geometry property of shadows. // Use a simplified example to illustrate the geometry setup here. // Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index c672bc433ca0..dff19a9e9c58 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -21,6 +21,7 @@ #include <SkMatrix.h> #include "Caches.h" +#include "Extensions.h" #include "Layer.h" #include "Matrix.h" #include "SkiaShader.h" diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 631305f77fe8..e110ca57d09b 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -24,16 +24,15 @@ #include <cutils/compiler.h> -#include "Extensions.h" -#include "ProgramCache.h" -#include "TextureCache.h" -#include "GradientCache.h" +#include "Matrix.h" namespace android { namespace uirenderer { class Caches; +class Extensions; class Layer; +struct ProgramDescription; /** * Type of Skia shader in use. @@ -62,8 +61,7 @@ public: // This shader is unsupported. Skip it. } static void setupProgram(Caches* caches, const mat4& modelViewMatrix, - GLuint* textureUnit, const Extensions& extensions, - const SkShader& shader) { + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { // This shader is unsupported. Skip it. } diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 3046fd5daacc..b3cfde2f7521 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -52,6 +52,7 @@ #include "ShadowTessellator.h" #include "SpotShadow.h" #include "Vertex.h" +#include "VertexBuffer.h" #include "utils/MathUtils.h" // TODO: After we settle down the new algorithm, we can remove the old one and diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h index e2d94f7ebc5c..62a7e5dc8a3e 100644 --- a/libs/hwui/SpotShadow.h +++ b/libs/hwui/SpotShadow.h @@ -19,11 +19,12 @@ #include "Debug.h" #include "Vector.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + class SpotShadow { public: static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter, diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h deleted file mode 100644 index fcd6060133cc..000000000000 --- a/libs/hwui/StatefulBaseRenderer.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -#ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H -#define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H - -#include <utils/RefBase.h> - -#include "Renderer.h" -#include "Snapshot.h" - -namespace android { -namespace uirenderer { - -/** - * Abstract Renderer subclass, which implements Canvas state methods. - * - * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the - * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have - * different use cases: - * - * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into - * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. - * - * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations - * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so - * that quickRejection can also be used. - */ -class StatefulBaseRenderer : public Renderer { -public: - StatefulBaseRenderer(); - - virtual status_t prepare(bool opaque) { - return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque); - } - - /** - * Initialize the first snapshot, computing the projection matrix, and stores the dimensions of - * the render target. - */ - virtual void setViewport(int width, int height); - void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, - const Vector3& lightCenter); - - // getters - bool hasRectToRectTransform() const { - return CC_LIKELY(currentTransform()->rectToRect()); - } - - // Save (layer) - virtual int getSaveCount() const { return mSaveCount; } - virtual int save(int flags); - virtual void restore(); - virtual void restoreToCount(int saveCount); - //virtual int saveLayer(float left, float top, float right, float bottom, - // int alpha, SkXfermode::Mode mode, int flags); - - // Matrix - virtual void getMatrix(SkMatrix* outMatrix) const; - virtual void translate(float dx, float dy, float dz = 0.0f); - virtual void rotate(float degrees); - virtual void scale(float sx, float sy); - virtual void skew(float sx, float sy); - - virtual void setMatrix(const SkMatrix& matrix); - void setMatrix(const Matrix4& matrix); // internal only convenience method - virtual void concatMatrix(const SkMatrix& matrix); - void concatMatrix(const Matrix4& matrix); // internal only convenience method - - // Clip - virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } - - virtual bool quickRejectConservative(float left, float top, float right, float bottom) const; - - virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); - virtual bool clipPath(const SkPath* path, SkRegion::Op op); - virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); - - /** - * Does not support different clipping Ops (that is, every call to setClippingOutline is - * effectively using SkRegion::kReplaceOp) - * - * The clipping outline is independent from the regular clip. - */ - void setClippingOutline(LinearAllocator& allocator, const Outline* outline); - void setClippingRoundRect(LinearAllocator& allocator, - const Rect& rect, float radius, bool highPriority = true); - - inline const mat4* currentTransform() const { - return mSnapshot->transform; - } - -protected: - const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } - - int getWidth() { return mWidth; } - int getHeight() { return mHeight; } - - // Save - int saveSnapshot(int flags); - void restoreSnapshot(); - - // allows subclasses to control what value is stored in snapshot's fbo field in - // initializeSaveStack - virtual GLuint getTargetFbo() const { - return -1; - } - - // Clip - bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, - bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; - - /** - * Called just after a restore has occurred. The 'removed' snapshot popped from the stack, - * 'restored' snapshot has become the top/current. - * - * Subclasses can override this method to handle layer restoration - */ - virtual void onSnapshotRestored(const Snapshot& removed, - const Snapshot& restored) {}; - - virtual void onViewportInitialized() {}; - - inline const Rect* currentClipRect() const { - return mSnapshot->clipRect; - } - - inline const Snapshot* currentSnapshot() const { - return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get(); - } - - inline const Snapshot* firstSnapshot() const { - return mFirstSnapshot.get(); - } - - // indicites that the clip has been changed since the last time it was consumed - bool mDirtyClip; - -private: - // Dimensions of the drawing surface - int mWidth, mHeight; - - // Number of saved states - int mSaveCount; - - // Base state - sp<Snapshot> mFirstSnapshot; - -protected: - // Current state - // TODO: should become private, once hooks needed by OpenGLRenderer are added - sp<Snapshot> mSnapshot; -}; // class StatefulBaseRenderer - -}; // namespace uirenderer -}; // namespace android - -#endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h index 7eca6816fe08..3efeaf64d486 100644 --- a/libs/hwui/TessellationCache.h +++ b/libs/hwui/TessellationCache.h @@ -24,7 +24,6 @@ #include "Debug.h" #include "utils/Macros.h" #include "utils/Pair.h" -#include "VertexBuffer.h" class SkBitmap; class SkCanvas; @@ -36,6 +35,7 @@ namespace android { namespace uirenderer { class Caches; +class VertexBuffer; /////////////////////////////////////////////////////////////////////////////// // Classes @@ -166,7 +166,7 @@ private: sp<TaskProcessor<VertexBuffer*> > mProcessor; LruCache<Description, Buffer*> mCache; class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> { - void operator()(Description& description, Buffer*& buffer); + void operator()(Description& description, Buffer*& buffer) override; }; BufferRemovedListener mBufferRemovedListener; @@ -178,9 +178,8 @@ private: // holds a pointer, and implicit strong ref to each shadow task of the frame LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*> mShadowCache; class BufferPairRemovedListener : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t*>*> { - void operator()(ShadowDescription& description, - Task<vertexBuffer_pair_t*>*& bufferPairTask) { - bufferPairTask->decStrong(NULL); + void operator()(ShadowDescription& description, Task<vertexBuffer_pair_t*>*& bufferPairTask) override { + bufferPairTask->decStrong(nullptr); } }; BufferPairRemovedListener mBufferPairRemovedListener; diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index 96c09e645196..a642c683071a 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -20,6 +20,7 @@ #include "Caches.h" #include "Debug.h" +#include "FontRenderer.h" #include "TextDropShadowCache.h" #include "Properties.h" diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index 54b930b1d984..caf089f6d2a5 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -24,17 +24,18 @@ #include <utils/LruCache.h> #include <utils/String16.h> -#include "FontRenderer.h" +#include "font/Font.h" #include "Texture.h" namespace android { namespace uirenderer { class Caches; +class FontRenderer; struct ShadowText { - ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL), - flags(0), italicStyle(0.0f), scaleX(0), text(NULL), positions(NULL) { + ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(nullptr), + flags(0), italicStyle(0.0f), scaleX(0), text(nullptr), positions(nullptr) { } // len is the number of bytes in text @@ -75,7 +76,7 @@ struct ShadowText { uint32_t charCount = len / sizeof(char16_t); str.setTo((const char16_t*) text, charCount); text = str.string(); - if (positions != NULL) { + if (positions != nullptr) { positionsCopy.clear(); positionsCopy.appendArray(positions, charCount * 2); positions = positionsCopy.array(); @@ -133,7 +134,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(ShadowText& text, ShadowTexture*& texture); + void operator()(ShadowText& text, ShadowTexture*& texture) override; ShadowTexture* get(const SkPaint* paint, const char* text, uint32_t len, int numGlyphs, float radius, const float* positions); diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 63454d8ef7c9..8109433d8aed 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -26,6 +26,7 @@ #include "AssetAtlas.h" #include "Caches.h" +#include "Texture.h" #include "TextureCache.h" #include "Properties.h" #include "utils/TraceUtils.h" diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index cf8d1349dc50..0e33e4c7e504 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -24,11 +24,12 @@ #include <utils/Vector.h> #include "Debug.h" -#include "Texture.h" namespace android { namespace uirenderer { +class Texture; + /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// @@ -61,7 +62,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(uint32_t&, Texture*& texture); + void operator()(uint32_t&, Texture*& texture) override; /** * Resets all Textures to not be marked as in use diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index ae6ea9474069..e820b2287da4 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -20,7 +20,6 @@ #include <utils/Timers.h> -#include "DamageAccumulator.h" #include "utils/Macros.h" namespace android { @@ -30,6 +29,7 @@ namespace renderthread { class CanvasContext; } +class DamageAccumulator; class OpenGLRenderer; class RenderState; diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h index 4ff0b183cfb6..fe8a7520a85a 100644 --- a/libs/hwui/Vertex.h +++ b/libs/hwui/Vertex.h @@ -39,8 +39,8 @@ struct Vertex { float x, y; static inline void set(Vertex* vertex, float x, float y) { - vertex[0].x = x; - vertex[0].y = y; + vertex->x = x; + vertex->y = y; } static inline void set(Vertex* vertex, Vector2 val) { diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h index 8c3a272bb389..d81dd42cde12 100644 --- a/libs/hwui/VertexBuffer.h +++ b/libs/hwui/VertexBuffer.h @@ -32,17 +32,17 @@ public: }; VertexBuffer() - : mBuffer(0) - , mIndices(0) + : mBuffer(nullptr) + , mIndices(nullptr) , mVertexCount(0) , mIndexCount(0) , mAllocatedVertexCount(0) , mAllocatedIndexCount(0) , mByteCount(0) , mMode(kStandard) - , mReallocBuffer(0) - , mCleanupMethod(NULL) - , mCleanupIndexMethod(NULL) + , mReallocBuffer(nullptr) + , mCleanupMethod(nullptr) + , mCleanupIndexMethod(nullptr) {} ~VertexBuffer() { diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp index 24ffb80c0053..380c0ed108e6 100644 --- a/libs/hwui/font/CacheTexture.cpp +++ b/libs/hwui/font/CacheTexture.cpp @@ -17,6 +17,7 @@ #include <SkGlyph.h> #include "CacheTexture.h" +#include "FontUtil.h" #include "../Caches.h" #include "../Debug.h" #include "../Extensions.h" diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h index 4cc4f22fe9d4..5d3f959c2b98 100644 --- a/libs/hwui/font/CacheTexture.h +++ b/libs/hwui/font/CacheTexture.h @@ -23,7 +23,6 @@ #include <utils/Log.h> -#include "FontUtil.h" #include "../PixelBuffer.h" #include "../Rect.h" #include "../Vertex.h" @@ -55,7 +54,7 @@ struct CacheBlock { CacheBlock* mPrev; CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height): - mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) { + mX(x), mY(y), mWidth(width), mHeight(height), mNext(nullptr), mPrev(nullptr) { } static CacheBlock* insertBlock(CacheBlock* head, CacheBlock* newBlock); @@ -147,7 +146,7 @@ public: } uint16_t* indices() const { - return (uint16_t*) 0; + return (uint16_t*) nullptr; } void resetMesh() { diff --git a/libs/hwui/font/CachedGlyphInfo.h b/libs/hwui/font/CachedGlyphInfo.h index 6680a00bc3f9..0642d59d9b16 100644 --- a/libs/hwui/font/CachedGlyphInfo.h +++ b/libs/hwui/font/CachedGlyphInfo.h @@ -19,11 +19,11 @@ #include <SkFixed.h> -#include "CacheTexture.h" - namespace android { namespace uirenderer { +class CacheTexture; + struct CachedGlyphInfo { // Has the cache been invalidated? bool mIsValid; diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index e1a38ddd70de..2e6c5282d10e 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -22,6 +22,7 @@ #include <utils/JenkinsHash.h> #include <utils/Trace.h> +#include <SkDeviceProperties.h> #include <SkGlyph.h> #include <SkGlyphCache.h> #include <SkUtils.h> @@ -41,9 +42,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// Font::Font(FontRenderer* state, const Font::FontDescription& desc) : - mState(state), mDescription(desc) { - mDeviceProperties = SkDeviceProperties::Make(SkDeviceProperties::Geometry::MakeDefault(), 1.0f); -} + mState(state), mDescription(desc) { } Font::FontDescription::FontDescription(const SkPaint* paint, const SkMatrix& rasterMatrix) : mLookupTransform(rasterMatrix) { @@ -139,8 +138,7 @@ void Font::invalidateTextureCache(CacheTexture* cacheTexture) { } void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, - uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, - const float* pos) { + uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) { int width = (int) glyph->mBitmapWidth; int height = (int) glyph->mBitmapHeight; @@ -162,8 +160,7 @@ void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, } void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, - uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, - const float* pos) { + uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) { float width = (float) glyph->mBitmapWidth; float height = (float) glyph->mBitmapHeight; @@ -182,8 +179,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, } void Font::drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y, - uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, - const float* pos) { + uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) { float width = (float) glyph->mBitmapWidth; float height = (float) glyph->mBitmapHeight; @@ -213,8 +209,7 @@ void Font::drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y, } void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, - uint32_t bitmapWidth, uint32_t bitmapHeight, Rect* bounds, - const float* pos) { + uint32_t bitmapWidth, uint32_t bitmapHeight, Rect* bounds, const float* pos) { int dstX = x + glyph->mBitmapLeft; int dstY = y + glyph->mBitmapTop; @@ -289,7 +284,8 @@ CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bo if (cachedGlyph) { // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { - SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform); + SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); + SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit); updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching); } @@ -479,7 +475,8 @@ CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool prec CachedGlyphInfo* newGlyph = new CachedGlyphInfo(); mCachedGlyphs.add(glyph, newGlyph); - SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform); + SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); + SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph); newGlyph->mIsValid = false; newGlyph->mGlyphIndex = skiaGlyph.fID; diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h index 0f1046436d1f..3119d734bc2b 100644 --- a/libs/hwui/font/Font.h +++ b/libs/hwui/font/Font.h @@ -22,13 +22,12 @@ #include <utils/KeyedVector.h> #include <SkScalar.h> -#include <SkDeviceProperties.h> #include <SkGlyphCache.h> #include <SkScalerContext.h> #include <SkPaint.h> #include <SkPathMeasure.h> -#include "CachedGlyphInfo.h" +#include "FontUtil.h" #include "../Rect.h" #include "../Matrix.h" @@ -39,6 +38,8 @@ namespace uirenderer { // Font /////////////////////////////////////////////////////////////////////////////// +struct CachedGlyphInfo; +class CacheTexture; class FontRenderer; /** @@ -119,7 +120,7 @@ private: void measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds, const float* positions); - void invalidateTextureCache(CacheTexture* cacheTexture = NULL); + void invalidateTextureCache(CacheTexture* cacheTexture = nullptr); CachedGlyphInfo* cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching); void updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph, @@ -150,7 +151,6 @@ private: DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs; bool mIdentityTransform; - SkDeviceProperties mDeviceProperties; }; inline int strictly_order_type(const Font::FontDescription& lhs, diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index b7e1752d3012..0e541690a5eb 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -47,14 +47,13 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mOpaque(!translucent) , mCanvas(NULL) , mHaveNewSurface(false) + , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) , mRootRenderNode(rootRenderNode) { - mAnimationContext = contextFactory->createAnimationContext(mRenderThread.timeLord()); mRenderThread.renderState().registerCanvasContext(this); } CanvasContext::~CanvasContext() { destroy(); - delete mAnimationContext; mRenderThread.renderState().unregisterCanvasContext(this); } @@ -128,8 +127,8 @@ bool CanvasContext::pauseSurface(ANativeWindow* window) { } // TODO: don't pass viewport size, it's automatic via EGL -void CanvasContext::setup(int width, int height, const Vector3& lightCenter, - float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { +void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius, + uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { if (!mCanvas) return; mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha); } @@ -224,24 +223,23 @@ void CanvasContext::draw() { profiler().unionDirty(&dirty); } - status_t status; if (!dirty.isEmpty()) { - status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, + mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque); } else { - status = mCanvas->prepare(mOpaque); + mCanvas->prepare(mOpaque); } Rect outBounds; - status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds); + mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds); profiler().draw(mCanvas); - mCanvas->finish(); + bool drew = mCanvas->finish(); profiler().markPlaybackEnd(); - if (status & DrawGlInfo::kStatusDrew) { + if (drew) { swapBuffers(); } else { mEglManager.cancelFrame(); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 0cc2c7c2811a..d7f2ebd16472 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -128,7 +128,7 @@ private: OpenGLRenderer* mCanvas; bool mHaveNewSurface; DamageAccumulator mDamageAccumulator; - AnimationContext* mAnimationContext; + std::unique_ptr<AnimationContext> mAnimationContext; const sp<RenderNode> mRootRenderNode; diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 8fb1b1011aa5..9b8bc6c9039a 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -19,6 +19,7 @@ #include <cutils/log.h> #include <cutils/properties.h> +#include "../Caches.h" #include "../RenderState.h" #include "RenderThread.h" diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 36ba3a935e89..4ad1c40647c4 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -339,16 +339,14 @@ void RenderProxy::trimMemory(int level) { } } -template <typename T> -void UNUSED(T) {} - - CREATE_BRIDGE0(fence) { // Intentionally empty - UNUSED(args); return NULL; } +template <typename T> +void UNUSED(T t) {} + void RenderProxy::fence() { SETUP_TASK(fence); UNUSED(args); diff --git a/libs/hwui/renderthread/RenderTask.cpp b/libs/hwui/renderthread/RenderTask.cpp index 13970bade02a..b14f580791c5 100644 --- a/libs/hwui/renderthread/RenderTask.cpp +++ b/libs/hwui/renderthread/RenderTask.cpp @@ -14,15 +14,8 @@ * limitations under the License. */ -// LOG_TAG is being provided by the Makefile, reset. -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "RenderTask" - #include "RenderTask.h" -#include <utils/Log.h> #include <utils/Condition.h> #include <utils/Mutex.h> diff --git a/libs/hwui/tests/Android.mk b/libs/hwui/tests/Android.mk index 7bdce7fe14bc..2fff07d728f1 100644 --- a/libs/hwui/tests/Android.mk +++ b/libs/hwui/tests/Android.mk @@ -15,34 +15,9 @@ # local_target_dir := $(TARGET_OUT_DATA)/local/tmp -LOCAL_PATH:= $(call my-dir) +LOCAL_PATH:= $(call my-dir)/.. include $(CLEAR_VARS) -LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES -LOCAL_CFLAGS += -Wno-unused-parameter -LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" - -LOCAL_SRC_FILES:= \ - TestContext.cpp \ - main.cpp - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/.. \ - external/skia/src/core - -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - libskia \ - libgui \ - libui \ - libhwui - -ifeq ($(WITH_MALLOC_LEAK_CHECK),true) - LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK -endif - LOCAL_MODULE_PATH := $(local_target_dir) LOCAL_MODULE:= hwuitest LOCAL_MODULE_TAGS := tests @@ -50,7 +25,10 @@ LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := hwuitest LOCAL_MODULE_STEM_64 := hwuitest64 -include external/stlport/libstlport.mk -include $(BUILD_EXECUTABLE) +include $(LOCAL_PATH)/Android.common.mk -include $(call all-makefiles-under,$(LOCAL_PATH)) +LOCAL_SRC_FILES += \ + tests/TestContext.cpp \ + tests/main.cpp + +include $(BUILD_EXECUTABLE) diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index d847d137cce6..ee16991d817d 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -66,7 +66,7 @@ sp<RenderNode> createCard(int x, int y, int width, int height) { return node; } -int main() { +int main(int argc, char* argv[]) { createTestEnvironment(); // create the native surface @@ -83,7 +83,7 @@ int main() { rootNode->setPropertyFieldsDirty(RenderNode::GENERIC); ContextFactory factory; - RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); + std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory)); proxy->loadSystemProperties(); proxy->initialize(surface); float lightX = width / 2.0; @@ -123,7 +123,6 @@ int main() { sleep(5); - delete proxy; rootNode->decStrong(0); printf("Success!\n"); diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index 5a933abc1dc2..10e8b9e0bead 100644 --- a/libs/hwui/thread/TaskManager.h +++ b/libs/hwui/thread/TaskManager.h @@ -84,8 +84,8 @@ private: void exit(); private: - virtual status_t readyToRun(); - virtual bool threadLoop(); + virtual status_t readyToRun() override; + virtual bool threadLoop() override; // Lock for the list of tasks mutable Mutex mLock; diff --git a/libs/hwui/thread/TaskProcessor.h b/libs/hwui/thread/TaskProcessor.h index d1269f0bd55a..eb4ab64a3e94 100644 --- a/libs/hwui/thread/TaskProcessor.h +++ b/libs/hwui/thread/TaskProcessor.h @@ -47,7 +47,7 @@ public: virtual void onProcess(const sp<Task<T> >& task) = 0; private: - virtual void process(const sp<TaskBase>& task) { + virtual void process(const sp<TaskBase>& task) override { sp<Task<T> > realTask = static_cast<Task<T>* >(task.get()); // This is the right way to do it but sp<> doesn't play nice // sp<Task<T> > realTask = static_cast<sp<Task<T> > >(task); diff --git a/libs/hwui/utils/SortedList.h b/libs/hwui/utils/SortedList.h index 2fa890a39f73..a2c8c52fcbc7 100644 --- a/libs/hwui/utils/SortedList.h +++ b/libs/hwui/utils/SortedList.h @@ -93,13 +93,13 @@ public: } protected: - virtual void do_construct(void* storage, size_t num) const; - virtual void do_destroy(void* storage, size_t num) const; - virtual void do_copy(void* dest, const void* from, size_t num) const; - virtual void do_splat(void* dest, const void* item, size_t num) const; - virtual void do_move_forward(void* dest, const void* from, size_t num) const; - virtual void do_move_backward(void* dest, const void* from, size_t num) const; - virtual int do_compare(const void* lhs, const void* rhs) const; + virtual void do_construct(void* storage, size_t num) const override; + virtual void do_destroy(void* storage, size_t num) const override; + virtual void do_copy(void* dest, const void* from, size_t num) const override; + virtual void do_splat(void* dest, const void* item, size_t num) const override; + virtual void do_move_forward(void* dest, const void* from, size_t num) const override; + virtual void do_move_backward(void* dest, const void* from, size_t num) const override; + virtual int do_compare(const void* lhs, const void* rhs) const override; }; // class SortedList /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/utils/SortedListImpl.h b/libs/hwui/utils/SortedListImpl.h index dc385b5f7b3a..b1018265566a 100644 --- a/libs/hwui/utils/SortedListImpl.h +++ b/libs/hwui/utils/SortedListImpl.h @@ -41,7 +41,7 @@ protected: virtual int do_compare(const void* lhs, const void* rhs) const = 0; private: - ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; + ssize_t _indexOrderOf(const void* item, size_t* order = nullptr) const; // these are made private, because they can't be used on a SortedVector // (they don't have an implementation either) |