diff options
Diffstat (limited to 'libs/hwui')
119 files changed, 2279 insertions, 2193 deletions
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index 5840107..6ec42c2 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 9660dc0..8eb1048 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 0000000..fba7254 --- /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 d0b9d82..aa8db26 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/AnimationContext.cpp b/libs/hwui/AnimationContext.cpp index a20bdae..097be08 100644 --- a/libs/hwui/AnimationContext.cpp +++ b/libs/hwui/AnimationContext.cpp @@ -59,7 +59,7 @@ void AnimationContext::startFrame(TreeInfo::TraversalMode mode) { "Missed running animations last frame!"); AnimationHandle* head = mNextFrameAnimations.mNextHandle; if (head) { - mNextFrameAnimations.mNextHandle = NULL; + mNextFrameAnimations.mNextHandle = nullptr; mCurrentFrameAnimations.mNextHandle = head; head->mPreviousHandle = &mCurrentFrameAnimations; } @@ -84,15 +84,15 @@ void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator, AnimationHandle::AnimationHandle(AnimationContext& context) : mContext(context) - , mPreviousHandle(NULL) - , mNextHandle(NULL) { + , mPreviousHandle(nullptr) + , mNextHandle(nullptr) { } AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context) : mRenderNode(&animatingNode) , mContext(context) - , mPreviousHandle(NULL) - , mNextHandle(NULL) { + , mPreviousHandle(nullptr) + , mNextHandle(nullptr) { mRenderNode->animators().setAnimationHandle(this); } @@ -114,7 +114,7 @@ void AnimationHandle::release() { LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(), "Releasing the handle for an RenderNode with outstanding animators!"); removeFromList(); - mRenderNode->animators().setAnimationHandle(NULL); + mRenderNode->animators().setAnimationHandle(nullptr); delete this; } @@ -135,8 +135,8 @@ void AnimationHandle::removeFromList() { if (mNextHandle) { mNextHandle->mPreviousHandle = mPreviousHandle; } - mPreviousHandle = NULL; - mNextHandle = NULL; + mPreviousHandle = nullptr; + mNextHandle = nullptr; } } /* namespace uirenderer */ diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 8bf2107..512e0e2 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" @@ -31,11 +32,10 @@ namespace uirenderer { ************************************************************/ BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) - : mTarget(NULL) + : mTarget(nullptr) , 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 35a4a09..1b3d8e7 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; @@ -62,7 +64,7 @@ public: void attach(RenderNode* target); virtual void onAttached() {} - void detach() { mTarget = 0; } + void detach() { mTarget = nullptr; } void pushStaging(AnimationContext& context); bool animate(AnimationContext& context); @@ -98,7 +100,7 @@ protected: float mDeltaValue; float mFromValue; - Interpolator* mInterpolator; + std::unique_ptr<Interpolator> mInterpolator; PlayState mStagingPlayState; PlayState mPlayState; bool mHasStartValue; @@ -137,10 +139,10 @@ public: ANDROID_API virtual uint32_t dirtyMask(); protected: - virtual float getValue(RenderNode* target) const; - virtual void setValue(RenderNode* target, float value); - virtual void onAttached(); - virtual void onStagingPlayStateChanged(); + virtual float getValue(RenderNode* target) const override; + virtual void setValue(RenderNode* target, float value) override; + virtual void onAttached() override; + virtual void onStagingPlayStateChanged() override; private: typedef bool (RenderProperties::*SetFloatProperty)(float value); @@ -160,8 +162,8 @@ public: ANDROID_API virtual uint32_t dirtyMask(); protected: - virtual float getValue(RenderNode* target) const; - virtual void setValue(RenderNode* target, float value); + virtual float getValue(RenderNode* target) const override; + virtual void setValue(RenderNode* target, float value) override; private: sp<CanvasPropertyPrimitive> mProperty; }; @@ -179,8 +181,8 @@ public: ANDROID_API virtual uint32_t dirtyMask(); protected: - virtual float getValue(RenderNode* target) const; - virtual void setValue(RenderNode* target, float value); + virtual float getValue(RenderNode* target) const override; + virtual void setValue(RenderNode* target, float value) override; private: sp<CanvasPropertyPaint> mProperty; PaintField mField; @@ -194,8 +196,8 @@ public: ANDROID_API virtual uint32_t dirtyMask(); protected: - virtual float getValue(RenderNode* target) const; - virtual void setValue(RenderNode* target, float value); + virtual float getValue(RenderNode* target) const override; + virtual void setValue(RenderNode* target, float value) override; private: int mCenterX, mCenterY; diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index c28fb88..966959a 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 { @@ -27,12 +29,12 @@ using namespace std; static void unref(BaseRenderNodeAnimator* animator) { animator->detach(); - animator->decStrong(0); + animator->decStrong(nullptr); } AnimatorManager::AnimatorManager(RenderNode& parent) : mParent(parent) - , mAnimationHandle(NULL) { + , mAnimationHandle(nullptr) { } AnimatorManager::~AnimatorManager() { @@ -41,7 +43,7 @@ AnimatorManager::~AnimatorManager() { } void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { - animator->incStrong(0); + animator->incStrong(nullptr); animator->attach(&mParent); mNewAnimators.push_back(animator.get()); } @@ -85,7 +87,7 @@ public: dirtyMask |= animator->dirtyMask(); bool remove = animator->animate(mContext); if (remove) { - animator->decStrong(0); + animator->decStrong(nullptr); } else { if (animator->isRunning()) { mInfo.out.hasAnimations = true; @@ -142,7 +144,7 @@ static void endStagingAnimator(BaseRenderNodeAnimator* animator) { if (animator->listener()) { animator->listener()->onAnimationFinished(animator); } - animator->decStrong(0); + animator->decStrong(nullptr); } void AnimatorManager::endAllStagingAnimators() { @@ -159,7 +161,7 @@ public: void operator() (BaseRenderNodeAnimator* animator) { animator->forceEndNow(mContext); - animator->decStrong(0); + animator->decStrong(nullptr); } private: diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h index d03d427..fb75eb8 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 52ca92d..4d2e3a0 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> @@ -47,7 +48,7 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) { } else { ALOGW("Could not create atlas image"); delete mImage; - mImage = NULL; + mImage = nullptr; } updateTextureId(); @@ -56,7 +57,7 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) { void AssetAtlas::terminate() { if (mImage) { delete mImage; - mImage = NULL; + mImage = nullptr; updateTextureId(); } } @@ -82,12 +83,12 @@ void AssetAtlas::updateTextureId() { AssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const { ssize_t index = mEntries.indexOfKey(bitmap); - return index >= 0 ? mEntries.valueAt(index) : NULL; + return index >= 0 ? mEntries.valueAt(index) : nullptr; } Texture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const { ssize_t index = mEntries.indexOfKey(bitmap); - return index >= 0 ? mEntries.valueAt(index)->texture : NULL; + return index >= 0 ? mEntries.valueAt(index)->texture : nullptr; } /** @@ -98,12 +99,12 @@ struct DelegateTexture: public Texture { DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { } virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, - bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { + bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override { mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget); } virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, - bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { + bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override { mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget); } diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h index fffd740..1772eff 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 4bbe6ed..107eb08 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 { @@ -50,7 +49,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// Caches::Caches(): Singleton<Caches>(), - mExtensions(Extensions::getInstance()), mInitialized(false), mRenderState(NULL) { + mExtensions(Extensions::getInstance()), mInitialized(false), mRenderState(nullptr) { init(); initFont(); initConstraints(); @@ -88,13 +87,13 @@ bool Caches::init() { glActiveTexture(gTextureUnits[0]); mTextureUnit = 0; - mRegionMesh = NULL; + mRegionMesh = nullptr; mMeshIndices = 0; mShadowStripsIndices = 0; blend = false; lastSrcMode = GL_ZERO; lastDstMode = GL_ZERO; - currentProgram = NULL; + currentProgram = nullptr; mFunctorsCount = 0; @@ -164,7 +163,7 @@ bool Caches::initProperties() { StencilClipDebug prevDebugStencilClip = debugStencilClip; char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) { + if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, nullptr) > 0) { INIT_LOGD(" Layers updates debug enabled: %s", property); debugLayersUpdates = !strcmp(property, "true"); } else { @@ -172,7 +171,7 @@ bool Caches::initProperties() { } debugOverdraw = false; - if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) { + if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) { INIT_LOGD(" Overdraw debug enabled: %s", property); if (!strcmp(property, "show")) { debugOverdraw = true; @@ -184,7 +183,7 @@ bool Caches::initProperties() { } // See Properties.h for valid values - if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, NULL) > 0) { + if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) { INIT_LOGD(" Stencil clip debug enabled: %s", property); if (!strcmp(property, "hide")) { debugStencilClip = kStencilHide; @@ -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; @@ -235,7 +233,7 @@ void Caches::terminate() { fboCache.clear(); programCache.clear(); - currentProgram = NULL; + currentProgram = nullptr; patchCache.clear(); @@ -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 2e179af..b0eebd7 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 88d6f68..9d2ccf1 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 { @@ -253,24 +257,13 @@ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, // round rect clip is required if RR clip exists, and geometry intersects its corners if (roundRectClipRequired) { - *roundRectClipRequired = mSnapshot->roundRectClipState != NULL + *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); } 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 0000000..9e6a9c3 --- /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/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp index 420e331..9bd3bdc 100644 --- a/libs/hwui/DamageAccumulator.cpp +++ b/libs/hwui/DamageAccumulator.cpp @@ -79,7 +79,7 @@ void DamageAccumulator::computeCurrentTransform(Matrix4* outMatrix) const { void DamageAccumulator::pushCommon() { if (!mHead->next) { DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack)); - nextFrame->next = 0; + nextFrame->next = nullptr; nextFrame->prev = mHead; mHead->next = nextFrame; } @@ -147,7 +147,7 @@ static DirtyStack* findParentRenderNode(DirtyStack* frame) { return frame; } } - return NULL; + return nullptr; } static DirtyStack* findProjectionReceiver(DirtyStack* frame) { @@ -160,7 +160,7 @@ static DirtyStack* findProjectionReceiver(DirtyStack* frame) { } } } - return NULL; + return nullptr; } static void applyTransforms(DirtyStack* frame, DirtyStack* end) { @@ -222,7 +222,7 @@ void DamageAccumulator::finish(SkRect* totalDirty) { LOG_ALWAYS_FATAL_IF(mHead->prev != mHead, "Cannot finish, mismatched push/pop calls! %p vs. %p", mHead->prev, mHead); // Root node never has a transform, so this is the fully mapped dirty rect *totalDirty = mHead->pendingDirty; - totalDirty->roundOut(); + totalDirty->roundOut(totalDirty); mHead->pendingDirty.setEmpty(); } diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index 6fd0151..a1a7e1a 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) override { 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,12 +117,11 @@ public: batchColor); #endif } - return status; } - virtual bool purelyDrawBatch() { return true; } + virtual bool purelyDrawBatch() override { return true; } - virtual bool coversBounds(const Rect& bounds) { + virtual bool coversBounds(const Rect& bounds) override { if (CC_LIKELY(!mAllOpsOpaque || !mBounds.contains(bounds) || count() == 1)) return false; Region uncovered(android::Rect(bounds.left, bounds.top, bounds.right, bounds.bottom)); @@ -235,30 +233,11 @@ 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; } - virtual void add(DrawOp* op, const DeferredDisplayState* state, bool opaqueOverBounds) { + virtual void add(DrawOp* op, const DeferredDisplayState* state, + bool opaqueOverBounds) override { DrawBatch::add(op, state, opaqueOverBounds); const int newClipSideFlags = state->mClipSideFlags; @@ -269,16 +248,17 @@ 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) override { 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) - renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : NULL); + renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : nullptr); DrawOp* op = mOps[0].op; DisplayListLogBuffer& buffer = DisplayListLogBuffer::getInstance(); @@ -289,13 +269,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 +292,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) override { DEFER_LOGD("replaying state op batch %p", this); renderer.restoreDisplayState(*mState); @@ -322,7 +301,6 @@ public: // renderer.restoreToCount directly int saveCount = -1; mOp->applyState(renderer, saveCount); - return DrawGlInfo::kStatusDone; } private: @@ -332,15 +310,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) override { DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount); renderer.restoreDisplayState(*mState); renderer.restoreToCount(mRestoreCount); - return DrawGlInfo::kStatusDone; } private: @@ -358,9 +335,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 @@ -371,7 +347,7 @@ class BarrierDebugBatch : public Batch { void DeferredDisplayList::resetBatchingState() { for (int i = 0; i < kOpBatch_Count; i++) { - mBatchLookup[i] = NULL; + mBatchLookup[i] = nullptr; mMergingBatches[i].clear(); } #if DEBUG_MERGE_BEHAVIOR @@ -541,7 +517,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { } // find the latest batch of the new op's type, and try to merge the new op into it - DrawBatch* targetBatch = NULL; + DrawBatch* targetBatch = nullptr; // insertion point of a new batch, will hopefully be immediately after similar batch // (eventually, should be similar shader) @@ -564,7 +540,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { // Try to merge with any existing batch with same mergeId. if (mMergingBatches[deferInfo.batchId].get(deferInfo.mergeId, targetBatch)) { if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op, state)) { - targetBatch = NULL; + targetBatch = nullptr; } } } else { @@ -590,7 +566,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { // NOTE: it may be possible to optimize for special cases where two operations // of the same batch/paint could swap order, such as with a non-mergeable // (clipped) and a mergeable text operation - targetBatch = NULL; + targetBatch = nullptr; #if DEBUG_DEFER DEFER_LOGD("op couldn't join batch %p, was intersected by batch %d", targetBatch, i); @@ -647,26 +623,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 +657,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) { @@ -700,7 +671,7 @@ void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) { // leave deferred state ops alone for simplicity (empty save restore pairs may now exist) if (mBatches[i] && mBatches[i]->purelyDrawBatch()) { delete mBatches[i]; - mBatches.replaceAt(NULL, i); + mBatches.replaceAt(nullptr, i); } } mEarliestUnclearedIndex = maxIndex + 1; diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index f7f30b1..c92ab91 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 d02455c..0792120 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -25,8 +25,8 @@ namespace android { namespace uirenderer { DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer) - : mSurfaceTexture(0) - , mTransform(0) + : mSurfaceTexture(nullptr) + , mTransform(nullptr) , mNeedsGLContextAttach(false) , mUpdateTexImage(false) , mLayer(layer) @@ -42,14 +42,14 @@ DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, L DeferredLayerUpdater::~DeferredLayerUpdater() { SkSafeUnref(mColorFilter); - setTransform(0); + setTransform(nullptr); mLayer->postDecStrong(); - mLayer = 0; + mLayer = nullptr; } void DeferredLayerUpdater::setPaint(const SkPaint* paint) { OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode); - SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL; + SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr; SkRefCnt_SafeAssign(mColorFilter, colorFilter); } @@ -70,7 +70,7 @@ bool DeferredLayerUpdater::apply() { } if (mTransform) { mLayer->getTransform().load(*mTransform); - setTransform(0); + setTransform(nullptr); } } return success; @@ -95,10 +95,10 @@ void DeferredLayerUpdater::doUpdateTexImage() { bool forceFilter = false; sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); - if (buffer != NULL) { + if (buffer != nullptr) { // 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 @@ -122,7 +122,7 @@ void DeferredLayerUpdater::detachSurfaceTexture() { // TODO: Elevate to fatal exception ALOGE("Failed to detach SurfaceTexture from context %d", err); } - mSurfaceTexture = 0; + mSurfaceTexture = nullptr; mLayer->clearTexture(); } } diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 84411ed..38d8e4a 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; @@ -69,7 +68,7 @@ public: ANDROID_API void setTransform(const SkMatrix* matrix) { delete mTransform; - mTransform = matrix ? new SkMatrix(*matrix) : 0; + mTransform = matrix ? new SkMatrix(*matrix) : nullptr; } ANDROID_API void setPaint(const SkPaint* paint); @@ -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 8953166..249ada0 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 a9a9148..cfd60ad 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 bc9e7bd..23b6cff 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 8a5e21d..1b5af49 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,14 +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) +#include "utils/PaintUtils.h" // Use OP_LOG for logging with arglist, OP_LOGS if just printing char* #define OP_LOGS(s) OP_LOG("%s", (s)) @@ -63,9 +58,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,12 +85,8 @@ public: class StateOp : public DisplayListOp { public: - StateOp() {}; - - virtual ~StateOp() {} - virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { // default behavior only affects immediate, deferrable state, issue directly to renderer applyState(deferStruct.mRenderer, saveCount); } @@ -105,7 +96,7 @@ public: * list to flush */ virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { applyState(replayStruct.mRenderer, saveCount); } @@ -119,7 +110,7 @@ public: : mPaint(paint), mQuickRejected(false) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { if (mQuickRejected && CC_LIKELY(useQuickReject)) { return; } @@ -128,15 +119,15 @@ public: } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { if (mQuickRejected && CC_LIKELY(useQuickReject)) { 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 +136,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 +188,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) { @@ -219,7 +204,7 @@ protected: if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) { return false; } - if (Renderer::isBlendedColorFilter(mPaint->getColorFilter())) { + if (PaintUtils::isBlendedColorFilter(mPaint->getColorFilter())) { return false; } } @@ -232,7 +217,7 @@ protected: } - const SkPaint* mPaint; // should be accessed via getPaint() when applying + const SkPaint* mPaint; bool mQuickRejected; }; @@ -260,7 +245,7 @@ public: // default empty constructor for bounds, to be overridden in child constructor body DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { } - virtual bool getLocalBounds(Rect& localBounds) { + virtual bool getLocalBounds(Rect& localBounds) override { localBounds.set(mLocalBounds); OpenGLRenderer::TextShadow textShadow; if (OpenGLRenderer::getTextShadow(mPaint, &textShadow)) { @@ -287,20 +272,20 @@ public: : mFlags(flags) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { int newSaveCount = deferStruct.mRenderer.save(mFlags); deferStruct.mDeferredList.addSave(deferStruct.mRenderer, this, newSaveCount); } - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.save(mFlags); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Save flags %x", mFlags); } - virtual const char* name() { return "Save"; } + virtual const char* name() override { return "Save"; } int getFlags() const { return mFlags; } private: @@ -313,21 +298,21 @@ public: : mCount(count) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { deferStruct.mDeferredList.addRestoreToCount(deferStruct.mRenderer, this, saveCount + mCount); deferStruct.mRenderer.restoreToCount(saveCount + mCount); } - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.restoreToCount(saveCount + mCount); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Restore to count %d", mCount); } - virtual const char* name() { return "RestoreToCount"; } + virtual const char* name() override { return "RestoreToCount"; } private: int mCount; @@ -339,7 +324,7 @@ public: : mArea(left, top, right, bottom) , mPaint(&mCachedPaint) , mFlags(flags) - , mConvexMask(NULL) { + , mConvexMask(nullptr) { mCachedPaint.setAlpha(alpha); } @@ -347,11 +332,11 @@ public: : mArea(left, top, right, bottom) , mPaint(paint) , mFlags(flags) - , mConvexMask(NULL) + , mConvexMask(nullptr) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { // NOTE: don't bother with actual saveLayer, instead issuing it at flush time int newSaveCount = deferStruct.mRenderer.getSaveCount(); deferStruct.mDeferredList.addSaveLayer(deferStruct.mRenderer, this, newSaveCount); @@ -362,17 +347,19 @@ public: mPaint, mFlags); } - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mPaint, mFlags, mConvexMask); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("SaveLayer%s of area " RECT_STRING, (isSaveLayerAlpha() ? "Alpha" : ""),RECT_ARGS(mArea)); } - virtual const char* name() { return isSaveLayerAlpha() ? "SaveLayerAlpha" : "SaveLayer"; } + virtual const char* name() override { + return isSaveLayerAlpha() ? "SaveLayerAlpha" : "SaveLayer"; + } int getFlags() { return mFlags; } @@ -403,15 +390,15 @@ public: TranslateOp(float dx, float dy) : mDx(dx), mDy(dy) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.translate(mDx, mDy); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Translate by %f %f", mDx, mDy); } - virtual const char* name() { return "Translate"; } + virtual const char* name() override { return "Translate"; } private: float mDx; @@ -423,15 +410,15 @@ public: RotateOp(float degrees) : mDegrees(degrees) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.rotate(mDegrees); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Rotate by %f degrees", mDegrees); } - virtual const char* name() { return "Rotate"; } + virtual const char* name() override { return "Rotate"; } private: float mDegrees; @@ -442,15 +429,15 @@ public: ScaleOp(float sx, float sy) : mSx(sx), mSy(sy) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.scale(mSx, mSy); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Scale by %f %f", mSx, mSy); } - virtual const char* name() { return "Scale"; } + virtual const char* name() override { return "Scale"; } private: float mSx; @@ -462,15 +449,15 @@ public: SkewOp(float sx, float sy) : mSx(sx), mSy(sy) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.skew(mSx, mSy); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Skew by %f %f", mSx, mSy); } - virtual const char* name() { return "Skew"; } + virtual const char* name() override { return "Skew"; } private: float mSx; @@ -482,11 +469,11 @@ public: SetMatrixOp(const SkMatrix& matrix) : mMatrix(matrix) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.setMatrix(mMatrix); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { if (mMatrix.isIdentity()) { OP_LOGS("SetMatrix (reset)"); } else { @@ -494,7 +481,7 @@ public: } } - virtual const char* name() { return "SetMatrix"; } + virtual const char* name() override { return "SetMatrix"; } private: const SkMatrix mMatrix; @@ -505,15 +492,15 @@ public: ConcatMatrixOp(const SkMatrix& matrix) : mMatrix(matrix) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.concatMatrix(mMatrix); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("ConcatMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix)); } - virtual const char* name() { return "ConcatMatrix"; } + virtual const char* name() override { return "ConcatMatrix"; } private: const SkMatrix mMatrix; @@ -524,7 +511,7 @@ public: ClipOp(SkRegion::Op op) : mOp(op) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { // NOTE: must defer op BEFORE applying state, since it may read clip deferStruct.mDeferredList.addClip(deferStruct.mRenderer, this); @@ -547,18 +534,18 @@ public: ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) : ClipOp(op), mArea(left, top, right, bottom) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea)); } - virtual const char* name() { return "ClipRect"; } + virtual const char* name() override { return "ClipRect"; } protected: - virtual bool isRect() { return true; } + virtual bool isRect() override { return true; } private: Rect mArea; @@ -569,17 +556,17 @@ public: ClipPathOp(const SkPath* path, SkRegion::Op op) : ClipOp(op), mPath(path) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.clipPath(mPath, mOp); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { SkRect bounds = mPath->getBounds(); OP_LOG("ClipPath bounds " RECT_STRING, bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); } - virtual const char* name() { return "ClipPath"; } + virtual const char* name() override { return "ClipPath"; } private: const SkPath* mPath; @@ -590,55 +577,22 @@ public: ClipRegionOp(const SkRegion* region, SkRegion::Op op) : ClipOp(op), mRegion(region) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { + virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { renderer.clipRegion(mRegion, mOp); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { SkIRect bounds = mRegion->getBounds(); OP_LOG("ClipRegion bounds %d %d %d %d", bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); } - virtual const char* name() { return "ClipRegion"; } + virtual const char* name() override { return "ClipRegion"; } 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 /////////////////////////////////////////////////////////////////////////////// @@ -648,11 +602,11 @@ public: DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint) : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint) , mBitmap(bitmap) - , mEntryValid(false), mEntry(NULL) { + , mEntryValid(false), mEntry(nullptr) { } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmap(mBitmap, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { + renderer.drawBitmap(mBitmap, mPaint); } AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) { @@ -672,8 +626,8 @@ 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, - const Vector<OpStatePair>& ops, const Rect& bounds) { + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, + const Vector<OpStatePair>& ops, const Rect& bounds) override { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -709,19 +663,19 @@ public: } } - return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], + renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], pureTranslate, bounds, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw bitmap %p at %f %f%s", mBitmap, mLocalBounds.left, mLocalBounds.top, mEntry ? " using AssetAtlas" : ""); } - virtual const char* name() { return "DrawBitmap"; } + virtual const char* name() override { return "DrawBitmap"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap; @@ -757,21 +711,21 @@ 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) override { + 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw bitmap %p src=" RECT_STRING ", dst=" RECT_STRING, mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); } - virtual const char* name() { return "DrawBitmapRect"; } + virtual const char* name() override { return "DrawBitmapRect"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; } @@ -785,18 +739,18 @@ 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) override { + renderer.drawBitmapData(mBitmap, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw bitmap %p", mBitmap); } - virtual const char* name() { return "DrawBitmapData"; } + virtual const char* name() override { return "DrawBitmapData"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; } }; @@ -809,19 +763,19 @@ 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) override { + renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, + mVertices, mColors, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); } - virtual const char* name() { return "DrawBitmapMesh"; } + virtual const char* name() override { return "DrawBitmapMesh"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; } @@ -838,8 +792,8 @@ public: DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) : DrawBoundedOp(left, top, right, bottom, paint), - mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL), - mEntryValid(false), mEntry(NULL) { + mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(nullptr), + mEntryValid(false), mEntry(nullptr) { }; AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) { @@ -865,8 +819,8 @@ 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, - const Vector<OpStatePair>& ops, const Rect& bounds) { + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, + const Vector<OpStatePair>& ops, const Rect& bounds) override { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -905,7 +859,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,27 +889,27 @@ 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) override { // 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw patch " RECT_STRING "%s", RECT_ARGS(mLocalBounds), mEntry ? " with AssetAtlas" : ""); } - virtual const char* name() { return "DrawPatch"; } + virtual const char* name() override { return "DrawPatch"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch; deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap; deferInfo.mergeable = state.mMatrix.isPureTranslate() && @@ -977,17 +931,17 @@ private: class DrawColorOp : public DrawOp { public: DrawColorOp(int color, SkXfermode::Mode mode) - : DrawOp(NULL), mColor(color), mMode(mode) {}; + : DrawOp(nullptr), mColor(color), mMode(mode) {}; - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawColor(mColor, mMode); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { + renderer.drawColor(mColor, mMode); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw color %#x, mode %d", mColor, mMode); } - virtual const char* name() { return "DrawColor"; } + virtual const char* name() override { return "DrawColor"; } private: int mColor; @@ -1001,7 +955,7 @@ public: DrawStrokableOp(const Rect& localBounds, const SkPaint* paint) : DrawBoundedOp(localBounds, paint) {}; - virtual bool getLocalBounds(Rect& localBounds) { + virtual bool getLocalBounds(Rect& localBounds) override { localBounds.set(mLocalBounds); if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { localBounds.outset(strokeWidthOutset()); @@ -1010,7 +964,7 @@ public: } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { if (mPaint->getPathEffect()) { deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; } else { @@ -1026,23 +980,23 @@ 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) override { + renderer.drawRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Rect " RECT_STRING, RECT_ARGS(mLocalBounds)); } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { DrawStrokableOp::onDefer(renderer, deferInfo, state); deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mPaint->getStyle() == SkPaint::kFill_Style; } - virtual const char* name() { return "DrawRect"; } + virtual const char* name() override { return "DrawRect"; } }; class DrawRectsOp : public DrawBoundedOp { @@ -1051,18 +1005,18 @@ 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) override { + renderer.drawRects(mRects, mCount, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Rects count %d", mCount); } - virtual const char* name() { return "DrawRects"; } + virtual const char* name() override { return "DrawRects"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = DeferredDisplayList::kOpBatch_Vertices; } @@ -1077,17 +1031,17 @@ 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) override { + renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw RoundRect " RECT_STRING ", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { DrawStrokableOp::onDefer(renderer, deferInfo, state); if (!mPaint->getPathEffect()) { renderer.getCaches().tessellationCache.precacheRoundRect(state.mMatrix, *mPaint, @@ -1095,7 +1049,7 @@ public: } } - virtual const char* name() { return "DrawRoundRect"; } + virtual const char* name() override { return "DrawRoundRect"; } private: float mRx; @@ -1109,17 +1063,17 @@ 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) override { + renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, + *mRx, *mRy, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw RoundRect Props " RECT_STRING ", rx %f, ry %f", *mLeft, *mTop, *mRight, *mBottom, *mRx, *mRy); } - virtual const char* name() { return "DrawRoundRectProps"; } + virtual const char* name() override { return "DrawRoundRectProps"; } private: float* mLeft; @@ -1136,15 +1090,15 @@ 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) override { + renderer.drawCircle(mX, mY, mRadius, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); } - virtual const char* name() { return "DrawCircle"; } + virtual const char* name() override { return "DrawCircle"; } private: float mX; @@ -1157,15 +1111,15 @@ 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) override { + renderer.drawCircle(*mX, *mY, *mRadius, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Circle Props x %p, y %p, r %p", mX, mY, mRadius); } - virtual const char* name() { return "DrawCircleProps"; } + virtual const char* name() override { return "DrawCircleProps"; } private: float* mX; @@ -1178,16 +1132,16 @@ 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) override { + renderer.drawOval(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Oval " RECT_STRING, RECT_ARGS(mLocalBounds)); } - virtual const char* name() { return "DrawOval"; } + virtual const char* name() override { return "DrawOval"; } }; class DrawArcOp : public DrawStrokableOp { @@ -1197,18 +1151,18 @@ 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) override { + 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Arc " RECT_STRING ", start %f, sweep %f, useCenter %d", RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); } - virtual const char* name() { return "DrawArc"; } + virtual const char* name() override { return "DrawArc"; } private: float mStartAngle; @@ -1228,23 +1182,22 @@ 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) override { + 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); + const DeferredDisplayState& state) override { + renderer.getCaches().pathCache.precache(mPath, mPaint); deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Path %p in " RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); } - virtual const char* name() { return "DrawPath"; } + virtual const char* name() override { return "DrawPath"; } private: const SkPath* mPath; @@ -1258,18 +1211,18 @@ 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) override { + renderer.drawLines(mPoints, mCount, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Lines count %d", mCount); } - virtual const char* name() { return "DrawLines"; } + virtual const char* name() override { return "DrawLines"; } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { deferInfo.batchId = mPaint->isAntiAlias() ? DeferredDisplayList::kOpBatch_AlphaVertices : DeferredDisplayList::kOpBatch_Vertices; @@ -1285,15 +1238,15 @@ 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) override { + renderer.drawPoints(mPoints, mCount, mPaint); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Points count %d", mCount); } - virtual const char* name() { return "DrawPoints"; } + virtual const char* name() override { return "DrawPoints"; } }; class DrawSomeTextOp : public DrawOp { @@ -1301,19 +1254,18 @@ public: DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint) : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw some text, %d bytes", mBytesCount); } - virtual bool hasTextShadow() const { + virtual bool hasTextShadow() const override { return OpenGLRenderer::hasTextShadow(mPaint); } 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()); + const DeferredDisplayState& state) override { + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint); + fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I()); deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? DeferredDisplayList::kOpBatch_Text : @@ -1335,12 +1287,12 @@ 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) override { + renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, + mHOffset, mVOffset, mPaint); } - virtual const char* name() { return "DrawTextOnPath"; } + virtual const char* name() override { return "DrawTextOnPath"; } private: const SkPath* mPath; @@ -1356,11 +1308,11 @@ 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) override { + renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint); } - virtual const char* name() { return "DrawPosText"; } + virtual const char* name() override { return "DrawPosText"; } private: const float* mPositions; @@ -1376,13 +1328,12 @@ public: } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); + const DeferredDisplayState& state) override { + 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 +1351,15 @@ public: && OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 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, - const Vector<OpStatePair>& ops, const Rect& bounds) { - status_t status = DrawGlInfo::kStatusDone; + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, + const Vector<OpStatePair>& ops, const Rect& bounds) override { 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,18 +1368,17 @@ 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount); } - virtual const char* name() { return "DrawText"; } + virtual const char* name() override { return "DrawText"; } private: const char* mText; @@ -1449,20 +1398,19 @@ private: class DrawFunctorOp : public DrawOp { public: DrawFunctorOp(Functor* functor) - : DrawOp(NULL), mFunctor(functor) {} + : DrawOp(nullptr), mFunctor(functor) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Functor %p", mFunctor); } - virtual const char* name() { return "DrawFunctor"; } + virtual const char* name() override { return "DrawFunctor"; } private: Functor* mFunctor; @@ -1473,36 +1421,35 @@ class DrawRenderNodeOp : public DrawBoundedOp { friend class DisplayListData; // grant DisplayListData access to info of child public: DrawRenderNodeOp(RenderNode* renderNode, int flags, const mat4& transformFromParent) - : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), 0), + : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr), mRenderNode(renderNode), mFlags(flags), mTransformFromParent(transformFromParent) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { mRenderNode->defer(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, - bool useQuickReject) { + bool useQuickReject) override { if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { mRenderNode->replay(replayStruct, level + 1); } } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { LOG_ALWAYS_FATAL("should not be called, because replay() is overridden"); - return 0; } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName(), mFlags); if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) { mRenderNode->output(level + 1); } } - virtual const char* name() { return "DrawRenderNode"; } + virtual const char* name() override { return "DrawRenderNode"; } RenderNode* renderNode() { return mRenderNode; } @@ -1537,7 +1484,7 @@ class DrawShadowOp : public DrawOp { public: DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float casterAlpha, const SkPath* casterOutline) - : DrawOp(NULL) + : DrawOp(nullptr) , mTransformXY(transformXY) , mTransformZ(transformZ) , mCasterAlpha(casterAlpha) @@ -1545,13 +1492,13 @@ public: } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, - const DeferredDisplayState& state) { + const DeferredDisplayState& state) override { renderer.getCaches().tessellationCache.precacheShadows(&state.mMatrix, renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline, &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius()); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { TessellationCache::vertexBuffer_pair_t buffers; Matrix4 drawTransform(*(renderer.currentTransform())); renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform, @@ -1559,14 +1506,14 @@ 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 { + virtual void output(int level, uint32_t logFlags) const override { OP_LOGS("DrawShadow"); } - virtual const char* name() { return "DrawShadow"; } + virtual const char* name() override { return "DrawShadow"; } private: bool isCasterOpaque() { return mCasterAlpha >= 1.0f; } @@ -1580,17 +1527,17 @@ private: class DrawLayerOp : public DrawOp { public: DrawLayerOp(Layer* layer, float x, float y) - : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {} + : DrawOp(nullptr), 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) override { + renderer.drawLayer(mLayer, mX, mY); } - virtual void output(int level, uint32_t logFlags) const { + virtual void output(int level, uint32_t logFlags) const override { OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY); } - virtual const char* name() { return "DrawLayer"; } + virtual const char* name() override { return "DrawLayer"; } private: Layer* mLayer; diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 42ac07e..ca21e4e 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -28,15 +28,18 @@ #include "DisplayListOp.h" #include "DisplayListRenderer.h" #include "RenderNode.h" +#include "utils/PaintUtils.h" namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer() - : mResourceCache(ResourceCache::getInstance()) - , mDisplayListData(NULL) + : mState(*this) + , mResourceCache(ResourceCache::getInstance()) + , mDisplayListData(nullptr) , mTranslateX(0.0f) , mTranslateY(0.0f) + , mHasDeferredTranslate(false) , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) , mRestoreSaveCount(-1) { @@ -56,29 +59,28 @@ DisplayListData* DisplayListRenderer::finishRecording() { mRegionMap.clear(); mPathMap.clear(); DisplayListData* data = mDisplayListData; - mDisplayListData = 0; + mDisplayListData = nullptr; return data; } -status_t DisplayListRenderer::prepareDirty(float left, float top, - float right, float bottom, bool opaque) { +void DisplayListRenderer::prepareDirty(float left, float top, + float right, float bottom) { 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(false); 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 +89,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); +int DisplayListRenderer::save(SkCanvas::SaveFlags flags) { + addStateOp(new (alloc()) SaveOp((int) flags)); + return mState.save((int) flags); } void DisplayListRenderer::restore() { @@ -107,179 +108,214 @@ 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, - const SkPaint* paint, int flags) { + const SkPaint* paint, SkCanvas::SaveFlags flags) { // force matrix/clip isolation for layer flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; paint = refPaint(paint); - addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); - return StatefulBaseRenderer::save(flags); + addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags)); + return mState.save((int) flags); } -void DisplayListRenderer::translate(float dx, float dy, float dz) { - // ignore dz, not used at defer time +void DisplayListRenderer::translate(float dx, float dy) { mHasDeferredTranslate = true; mTranslateX += dx; mTranslateY += dy; flushRestoreToCount(); - StatefulBaseRenderer::translate(dx, dy, dz); + mState.translate(dx, dy, 0.0f); } 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) { +void DisplayListRenderer::concat(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); - StatefulBaseRenderer::concatMatrix(matrix); + mState.concatMatrix(matrix); +} + +bool DisplayListRenderer::getClipBounds(SkRect* outRect) const { + Rect bounds = mState.getLocalClipBounds(); + *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom); + return !(outRect->isEmpty()); +} + +bool DisplayListRenderer::quickRejectRect(float left, float top, float right, float bottom) const { + return mState.quickRejectConservative(left, top, right, bottom); +} + +bool DisplayListRenderer::quickRejectPath(const SkPath& path) const { + SkRect bounds = path.getBounds(); + return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); } + 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 left, float top, + const SkPaint* paint) { + save(SkCanvas::kMatrix_SaveFlag); + translate(left, top); + drawBitmap(&bitmap, paint); + restore(); +} + +void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, + const SkPaint* paint) { + if (matrix.isIdentity()) { + drawBitmap(&bitmap, paint); + } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))) { + // SkMatrix::isScaleTranslate() not available in L + SkRect src; + SkRect dst; + bitmap.getBounds(&src); + matrix.mapRect(&dst, src); + drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, + dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); + } else { + save(SkCanvas::kMatrix_SaveFlag); + concat(matrix); + drawBitmap(&bitmap, paint); + restore(); + } +} + +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 - && srcRight == bitmap->width() && srcBottom == bitmap->height() + && srcRight == bitmap.width() && srcBottom == bitmap.height() && (srcBottom - srcTop == dstBottom - dstTop) && (srcRight - srcLeft == dstRight - dstLeft)) { // transform simple rect to rect drawing case into position bitmap ops, since they merge save(SkCanvas::kMatrix_SaveFlag); translate(dstLeft, dstTop); - drawBitmap(bitmap, paint); + drawBitmap(&bitmap, paint); restore(); } else { - bitmap = refBitmap(bitmap); paint = refPaint(paint); - addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, + addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), 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); vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex paint = refPaint(paint); colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex - addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, - vertices, colors, paint)); - return DrawGlInfo::kStatusDone; + addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(&bitmap), meshWidth, meshHeight, + vertices, colors, paint)); } -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, - const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawPaint(const SkPaint& paint) { + SkRect bounds; + if (getClipBounds(&bounds)) { + drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); + } } -status_t 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; + +void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, + const SkPaint& paint) { + addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint))); +} + +void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint))); } -status_t DisplayListRenderer::drawRoundRect( +void DisplayListRenderer::drawRoundRect( CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, @@ -293,16 +329,13 @@ 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) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); - return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint))); } -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,143 +343,121 @@ 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, - const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, + const SkPaint& paint) { + addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint))); } -status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { +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 { + addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, + startAngle, sweepAngle, useCenter, refPaint(&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) { - path = refPath(path); - paint = refPaint(paint); - - addDrawOp(new (alloc()) DrawPathOp(path, paint)); - return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawPath(const SkPath& path, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint))); } -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; + addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint))); } -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; + addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint))); } -status_t 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; - - text = refText(text, bytesCount); - path = refPath(path); - paint = refPaint(paint); +void DisplayListRenderer::drawTextOnPath(const uint16_t* glyphs, int count, + const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { + if (!glyphs || count <= 0) return; - DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, - hOffset, vOffset, paint); + int bytesCount = 2 * count; + DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount), + bytesCount, count, refPath(&path), + hOffset, vOffset, refPaint(&paint)); addDrawOp(op); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawPosText(const uint16_t* text, const float* positions, + int count, int posCount, const SkPaint& paint) { + if (!text || count <= 0) return; - text = refText(text, bytesCount); + int bytesCount = 2 * count; positions = refBuffer<float>(positions, count * 2); - paint = refPaint(paint); - DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); + DrawOp* op = new (alloc()) DrawPosTextOp(refText((const char*) text, bytesCount), + bytesCount, count, positions, refPaint(&paint)); addDrawOp(op); - return DrawGlInfo::kStatusDone; } static void simplifyPaint(int color, SkPaint* paint) { paint->setColor(color); - paint->setShader(NULL); - paint->setColorFilter(NULL); - paint->setLooper(NULL); + paint->setShader(nullptr); + paint->setColorFilter(nullptr); + paint->setLooper(nullptr); paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); paint->setStrokeJoin(SkPaint::kRound_Join); - paint->setLooper(NULL); + paint->setLooper(nullptr); } -status_t 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) { +void DisplayListRenderer::drawText(const uint16_t* glyphs, const float* positions, + int count, const SkPaint& paint, float x, float y, + float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, + float totalAdvance) { - if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone; + if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; - text = refText(text, bytesCount); + int bytesCount = count * 2; + const char* text = refText((const char*) glyphs, bytesCount); positions = refBuffer<float>(positions, count * 2); + Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); if (CC_UNLIKELY(mHighContrastText)) { // high contrast draw path - int color = paint->getColor(); + int color = paint.getColor(); int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); bool darken = channelSum < (128 * 3); // outline - SkPaint* outlinePaint = copyPaint(paint); + SkPaint* outlinePaint = copyPaint(&paint); simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? // inner - SkPaint* innerPaint = copyPaint(paint); + SkPaint* innerPaint = copyPaint(&paint); simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); innerPaint->setStyle(SkPaint::kFill_Style); addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, innerPaint, totalAdvance, bounds)); } else { // standard draw path - paint = refPaint(paint); - DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, paint, totalAdvance, bounds); + x, y, positions, refPaint(&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) { @@ -505,7 +516,7 @@ size_t DisplayListRenderer::addStateOp(StateOp* op) { size_t DisplayListRenderer::addDrawOp(DrawOp* op) { Rect localBounds; if (op->getLocalBounds(localBounds)) { - bool rejected = quickRejectConservative(localBounds.left, localBounds.top, + bool rejected = quickRejectRect(localBounds.left, localBounds.top, localBounds.right, localBounds.bottom); op->setQuickRejected(rejected); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2cc2be3..01fcdd3 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -17,13 +17,21 @@ #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 <private/graphics/Canvas.h> + +#include "CanvasState.h" +#include "DisplayList.h" #include "DisplayListLogBuffer.h" #include "RenderNode.h" +#include "Renderer.h" #include "ResourceCache.h" namespace android { @@ -48,13 +56,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 Canvas, public CanvasStateClient { public: DisplayListRenderer(); virtual ~DisplayListRenderer(); @@ -64,104 +74,181 @@ public: DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- -// Frame state operations +// HWUI Frame state operations // ---------------------------------------------------------------------------- - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); - virtual void interrupt(); - virtual void resume(); + + void prepareDirty(float left, float top, float right, float bottom); + void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); } + bool finish(); + void interrupt(); + void resume(); // ---------------------------------------------------------------------------- -// Canvas state operations +// HWUI Canvas state operations // ---------------------------------------------------------------------------- - // Save (layer) - virtual int save(int flags); - virtual void restore(); - virtual void restoreToCount(int saveCount); - virtual int saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags); - - // 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 setMatrix(const SkMatrix& matrix); - virtual void concatMatrix(const SkMatrix& matrix); - // 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); + void setViewport(int width, int height) { mState.setViewport(width, height); } - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } bool isCurrentTransformSimple() { - return currentTransform()->isSimple(); + return mState.currentTransform()->isSimple(); } // ---------------------------------------------------------------------------- -// Canvas draw operations +// HWUI Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t drawColor(int color, SkXfermode::Mode mode); // Bitmap-based - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t 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, + void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + // TODO: move drawBitmapData() to Canvas.h + void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); + // TODO: move drawPatch() to Canvas.h + void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); // 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, + void drawRects(const float* rects, int count, const SkPaint* paint); + 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, + 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); - // Text - virtual status_t 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); // ---------------------------------------------------------------------------- -// Canvas draw operations - special +// HWUI 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); + void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); + void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + void callDrawGLFunction(Functor* functor, Rect& dirty); void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } + +// ---------------------------------------------------------------------------- +// CanvasStateClient interface +// ---------------------------------------------------------------------------- + virtual void onViewportInitialized() override { } + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { } + virtual GLuint onGetTargetFbo() const override { return -1; } + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas interface +// ---------------------------------------------------------------------------- + virtual SkCanvas* getSkCanvas() override { + LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas"); + return nullptr; + } + virtual void setBitmap(SkBitmap* bitmap, bool copyState) override { + LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap."); + } + + virtual bool isOpaque() override { return false; } + virtual int width() override { return mState.getWidth(); } + virtual int height() override { return mState.getHeight(); } + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas state operations +// ---------------------------------------------------------------------------- + // Save (layer) + virtual int getSaveCount() const override { return mState.getSaveCount(); } + virtual int save(SkCanvas::SaveFlags 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, + SkCanvas::SaveFlags flags) override; + virtual int saveLayerAlpha(float left, float top, float right, float bottom, + int alpha, SkCanvas::SaveFlags flags) override { + SkPaint paint; + paint.setAlpha(alpha); + return saveLayer(left, top, right, bottom, &paint, flags); + } + + // Matrix + virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } + virtual void setMatrix(const SkMatrix& matrix) override; + + virtual void concat(const SkMatrix& matrix) override; + virtual void rotate(float degrees) override; + virtual void scale(float sx, float sy) override; + virtual void skew(float sx, float sy) override; + virtual void translate(float dx, float dy) override; + + // Clip + virtual bool getClipBounds(SkRect* outRect) const override; + virtual bool quickRejectRect(float left, float top, float right, float bottom) const override; + virtual bool quickRejectPath(const SkPath& path) const override; + + 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 SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); } + virtual void setDrawFilter(SkDrawFilter* filter) override; + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas draw operations +// ---------------------------------------------------------------------------- + virtual void drawColor(int color, SkXfermode::Mode mode) override; + virtual void drawPaint(const SkPaint& paint) override; + + // Geometry + virtual void drawPoint(float x, float y, const SkPaint& paint) override { + float points[2] = { x, y }; + drawPoints(points, 2, paint); + } + virtual void drawPoints(const float* points, int count, const SkPaint& paint) override; + virtual void drawLine(float startX, float startY, float stopX, float stopY, + const SkPaint& paint) override { + float points[4] = { startX, startY, stopX, stopY }; + drawLines(points, 4, paint); + } + virtual void drawLines(const float* points, int count, const SkPaint& paint) 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 drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount, + const float* verts, const float* tex, const int* colors, + const uint16_t* indices, int indexCount, const SkPaint& paint) override + { LOG_ALWAYS_FATAL("DisplayListRenderer does not support drawVertices()"); } + + // Bitmap-based + virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) override; + virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, + 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) override; + virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint) override; + + // Text + virtual void drawText(const uint16_t* glyphs, const float* positions, int count, + const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, + float boundsRight, float boundsBottom, float totalAdvance) override; + virtual void drawPosText(const uint16_t* text, const float* positions, int count, + int posCount, const SkPaint& paint) override; + virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + float hOffset, float vOffset, const SkPaint& paint) override; + virtual bool drawTextAbsolutePos() const override { return false; } + + private: + + CanvasState mState; + enum DeferredBarrierType { kBarrier_None, kBarrier_InOrder, @@ -186,7 +273,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 +285,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 +348,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 +384,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 +399,8 @@ private: int mRestoreSaveCount; + SkAutoTUnref<SkDrawFilter> mDrawFilter; + friend class RenderNode; }; // class DisplayListRenderer diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp index 77006a4..12d9389 100644 --- a/libs/hwui/Dither.cpp +++ b/libs/hwui/Dither.cpp @@ -24,7 +24,7 @@ namespace uirenderer { // Lifecycle /////////////////////////////////////////////////////////////////////////////// -Dither::Dither(): mCaches(NULL), mInitialized(false), mDitherTexture(0) { +Dither::Dither(): mCaches(nullptr), mInitialized(false), mDitherTexture(0) { } void Dither::bindDitherTexture() { diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h index 546236b..092ebf2 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/DrawProfiler.cpp b/libs/hwui/DrawProfiler.cpp index e590642..ecde5ff 100644 --- a/libs/hwui/DrawProfiler.cpp +++ b/libs/hwui/DrawProfiler.cpp @@ -59,7 +59,7 @@ static int dpToPx(int dp, float density) { DrawProfiler::DrawProfiler() : mType(kNone) , mDensity(0) - , mData(NULL) + , mData(nullptr) , mDataSize(0) , mCurrentFrame(-1) , mPreviousTime(0) @@ -160,7 +160,7 @@ void DrawProfiler::createData() { void DrawProfiler::destroyData() { delete mData; - mData = NULL; + mData = nullptr; } void DrawProfiler::addRect(Rect& r, float data, float* shapeOutput) { diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp index 84e7e65..8352c3f 100644 --- a/libs/hwui/Extensions.cpp +++ b/libs/hwui/Extensions.cpp @@ -66,7 +66,7 @@ Extensions::Extensions(): Singleton<Extensions>() { findExtensions(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS), mEglExtensionList); char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_DEBUG_NV_PROFILING, property, NULL) > 0) { + if (property_get(PROPERTY_DEBUG_NV_PROFILING, property, nullptr) > 0) { mHasNvSystemTime = !strcmp(property, "true") && hasEglExtension("EGL_NV_system_time"); } else { mHasNvSystemTime = false; diff --git a/libs/hwui/FboCache.cpp b/libs/hwui/FboCache.cpp index beef7be..b54d532 100644 --- a/libs/hwui/FboCache.cpp +++ b/libs/hwui/FboCache.cpp @@ -31,7 +31,7 @@ namespace uirenderer { FboCache::FboCache(): mMaxSize(DEFAULT_FBO_CACHE_SIZE) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_FBO_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_FBO_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting fbo cache size to %s", property); mMaxSize = atoi(property); } else { diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h index f175e98..fc29f7a 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 5b5b098..a0bc7b0 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -104,10 +104,10 @@ FontRenderer::FontRenderer() : INIT_LOGD("Creating FontRenderer"); } - mGammaTable = NULL; + mGammaTable = nullptr; mInitialized = false; - mCurrentCacheTexture = NULL; + mCurrentCacheTexture = nullptr; mLinearFiltering = false; @@ -117,19 +117,19 @@ FontRenderer::FontRenderer() : mLargeCacheHeight = DEFAULT_TEXT_LARGE_CACHE_HEIGHT; char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_TEXT_SMALL_CACHE_WIDTH, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_SMALL_CACHE_WIDTH, property, nullptr) > 0) { mSmallCacheWidth = atoi(property); } - if (property_get(PROPERTY_TEXT_SMALL_CACHE_HEIGHT, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_SMALL_CACHE_HEIGHT, property, nullptr) > 0) { mSmallCacheHeight = atoi(property); } - if (property_get(PROPERTY_TEXT_LARGE_CACHE_WIDTH, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_LARGE_CACHE_WIDTH, property, nullptr) > 0) { mLargeCacheWidth = atoi(property); } - if (property_get(PROPERTY_TEXT_LARGE_CACHE_HEIGHT, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_LARGE_CACHE_HEIGHT, property, nullptr) > 0) { mLargeCacheHeight = atoi(property); } @@ -213,7 +213,7 @@ CacheTexture* FontRenderer::cacheBitmapInTexture(Vector<CacheTexture*>& cacheTex } } // Could not fit glyph into current cache textures - return NULL; + return nullptr; } void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, @@ -224,7 +224,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp // so we can avoid doing extra work later on if (glyph.fWidth == 0 || glyph.fHeight == 0) { cachedGlyph->mIsValid = true; - cachedGlyph->mCacheTexture = NULL; + cachedGlyph->mCacheTexture = nullptr; return; } @@ -232,7 +232,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp // choose an appropriate cache texture list for this glyph format SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat); - Vector<CacheTexture*>* cacheTextures = NULL; + Vector<CacheTexture*>* cacheTextures = nullptr; switch (format) { case SkMask::kA8_Format: case SkMask::kBW_Format: @@ -598,7 +598,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co DropShadow image; image.width = 0; image.height = 0; - image.image = NULL; + image.image = nullptr; image.penX = 0; image.penY = 0; @@ -607,8 +607,8 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co } mDrawn = false; - mClip = NULL; - mBounds = NULL; + mClip = nullptr; + mBounds = nullptr; Rect bounds; mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); @@ -644,7 +644,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co // NOTE: bounds.isEmpty() can't be used here, since vertical coordinates are inverted // TODO: don't draw pure whitespace in the first place, and avoid needing this check mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY, - Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, NULL, positions); + Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, nullptr, positions); // Unbind any PBO we might have used Caches::getInstance().unbindPixelBuffer(); @@ -671,8 +671,8 @@ void FontRenderer::initRender(const Rect* clip, Rect* bounds, Functor* functor) } void FontRenderer::finishRender() { - mBounds = NULL; - mClip = NULL; + mBounds = nullptr; + mClip = nullptr; issueDrawCommand(); } @@ -724,7 +724,7 @@ void FontRenderer::removeFont(const Font* font) { mActiveFonts.remove(font->getDescription()); if (mCurrentFont == font) { - mCurrentFont = NULL; + mCurrentFont = nullptr; } } @@ -734,7 +734,7 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, flo if (width * height * intRadius >= RS_MIN_INPUT_CUTOFF) { uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); - if (mRs == 0) { + if (mRs == nullptr) { mRs = new RSC::RS(); // a null path is OK because there are no custom kernels used // hence nothing gets cached by RS @@ -746,7 +746,7 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, flo mRsScript = RSC::ScriptIntrinsicBlur::create(mRs, mRsElement); } } - if (mRs != 0) { + if (mRs != nullptr) { RSC::sp<const RSC::Type> t = RSC::Type::create(mRs, mRsElement, width, height, 0); RSC::sp<RSC::Allocation> ain = RSC::Allocation::createTyped(mRs, t, RS_ALLOCATION_MIPMAP_NONE, @@ -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 5c96c6b..668ee64 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 06d2aad..e97a477 100644 --- a/libs/hwui/GammaFontRenderer.cpp +++ b/libs/hwui/GammaFontRenderer.cpp @@ -61,7 +61,7 @@ GammaFontRenderer::GammaFontRenderer() { // Get the gamma mGamma = DEFAULT_TEXT_GAMMA; - if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_GAMMA, property, nullptr) > 0) { INIT_LOGD(" Setting text gamma to %s", property); mGamma = atof(property); } else { @@ -70,7 +70,7 @@ GammaFontRenderer::GammaFontRenderer() { // Get the black gamma threshold mBlackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD; - if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, nullptr) > 0) { INIT_LOGD(" Setting text black gamma threshold to %s", property); mBlackThreshold = atoi(property); } else { @@ -80,7 +80,7 @@ GammaFontRenderer::GammaFontRenderer() { // Get the white gamma threshold mWhiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD; - if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) { + if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, nullptr) > 0) { INIT_LOGD(" Setting text white gamma threshold to %s", property); mWhiteThreshold = atoi(property); } else { @@ -98,13 +98,13 @@ GammaFontRenderer::~GammaFontRenderer() { ShaderGammaFontRenderer::ShaderGammaFontRenderer(bool multiGamma): GammaFontRenderer() { INIT_LOGD("Creating shader gamma font renderer"); - mRenderer = NULL; + mRenderer = nullptr; mMultiGamma = multiGamma; } void ShaderGammaFontRenderer::describe(ProgramDescription& description, const SkPaint* paint) const { - if (paint->getShader() == NULL) { + if (paint->getShader() == nullptr) { if (mMultiGamma) { const int l = luminance(paint); @@ -149,7 +149,7 @@ LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() { mGammaTable[i] = uint8_t((float)::floor(pow(i / 255.0f, gamma) * 255.0f + 0.5f)); } - mRenderer = NULL; + mRenderer = nullptr; } void LookupGammaFontRenderer::endPrecaching() { @@ -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,18 +225,16 @@ 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) { - if (paint->getShader() == NULL) { + if (paint->getShader() == nullptr) { const int l = luminance(paint); if (l <= mBlackThreshold) { diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h index 46cfd04..19352d7 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 ffd1e8c..0987d9b 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)); } /////////////////////////////////////////////////////////////////////////////// @@ -66,7 +66,7 @@ GradientCache::GradientCache(): mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting gradient cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 6a783b1..9176c76 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 0e62d77..e1b0fc3 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 dfa0a85..66ce119 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> @@ -37,13 +38,13 @@ protected: class ANDROID_API AccelerateDecelerateInterpolator : public Interpolator { public: - virtual float interpolate(float input); + virtual float interpolate(float input) override; }; class ANDROID_API AccelerateInterpolator : public Interpolator { public: AccelerateInterpolator(float factor) : mFactor(factor), mDoubleFactor(factor*2) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mFactor; const float mDoubleFactor; @@ -52,7 +53,7 @@ private: class ANDROID_API AnticipateInterpolator : public Interpolator { public: AnticipateInterpolator(float tension) : mTension(tension) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mTension; }; @@ -60,20 +61,20 @@ private: class ANDROID_API AnticipateOvershootInterpolator : public Interpolator { public: AnticipateOvershootInterpolator(float tension) : mTension(tension) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mTension; }; class ANDROID_API BounceInterpolator : public Interpolator { public: - virtual float interpolate(float input); + virtual float interpolate(float input) override; }; class ANDROID_API CycleInterpolator : public Interpolator { public: CycleInterpolator(float cycles) : mCycles(cycles) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mCycles; }; @@ -81,20 +82,20 @@ private: class ANDROID_API DecelerateInterpolator : public Interpolator { public: DecelerateInterpolator(float factor) : mFactor(factor) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mFactor; }; class ANDROID_API LinearInterpolator : public Interpolator { public: - virtual float interpolate(float input) { return input; } + virtual float interpolate(float input) override { return input; } }; class ANDROID_API OvershootInterpolator : public Interpolator { public: OvershootInterpolator(float tension) : mTension(tension) {} - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: const float mTension; }; @@ -104,10 +105,10 @@ public: LUTInterpolator(float* values, size_t size); ~LUTInterpolator(); - virtual float interpolate(float input); + virtual float interpolate(float input) override; private: - float* mValues; + std::unique_ptr<float[]> mValues; size_t mSize; }; diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 9aa29ca..7388e3c 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -44,25 +44,23 @@ Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth , type(layerType) { // TODO: This is a violation of Android's typical ref counting, but it // preserves the old inc/dec ref locations. This should be changed... - incStrong(0); - mesh = NULL; + incStrong(nullptr); + mesh = nullptr; meshElementCount = 0; cacheable = true; dirty = false; renderTarget = GL_TEXTURE_2D; texture.width = layerWidth; texture.height = layerHeight; - colorFilter = NULL; + colorFilter = nullptr; deferredUpdateScheduled = false; - renderer = NULL; - renderNode = NULL; + renderNode = nullptr; fbo = 0; - stencil = NULL; + stencil = nullptr; debugDrawUpdate = false; hasDrawnSinceUpdate = false; forceFilter = false; - deferredList = NULL; - convexMask = NULL; + convexMask = nullptr; rendererLightPosDirty = true; wasBuildLayered = false; renderState.registerLayer(this); @@ -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(); } } @@ -160,7 +156,7 @@ void Layer::removeFbo(bool flush) { renderState.bindFramebuffer(previousFbo); caches.renderBufferCache.put(stencil); - stencil = NULL; + stencil = nullptr; } if (fbo) { @@ -181,7 +177,7 @@ void Layer::updateDeferred(RenderNode* renderNode, int left, int top, int right, void Layer::setPaint(const SkPaint* paint) { OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); - setColorFilter((paint) ? paint->getColorFilter() : NULL); + setColorFilter((paint) ? paint->getColorFilter() : nullptr); } void Layer::setColorFilter(SkColorFilter* filter) { @@ -225,7 +221,7 @@ void Layer::allocateTexture() { if (texture.id) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } } @@ -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); @@ -258,19 +253,16 @@ void Layer::defer(const OpenGLRenderer& rootRenderer) { } void Layer::cancelDefer() { - renderNode = NULL; + renderNode = nullptr; deferredUpdateScheduled = false; - if (deferredList) { - delete deferredList; - deferredList = NULL; - } + deferredList.release(); } void Layer::flush() { // renderer is checked as layer may be destroyed/put in layer cache with flush scheduled if (deferredList && renderer) { ATRACE_LAYER_WORK("Issue"); - renderer->startMark((renderNode.get() != NULL) ? renderNode->getName() : "Layer"); + renderer->startMark((renderNode.get() != nullptr) ? renderNode->getName() : "Layer"); renderer->setViewport(layer.getWidth(), layer.getHeight()); renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, @@ -281,7 +273,7 @@ void Layer::flush() { renderer->finish(); dirtyRect.setEmpty(); - renderNode = NULL; + renderNode = nullptr; renderer->endMark(); } @@ -302,7 +294,7 @@ void Layer::render(const OpenGLRenderer& rootRenderer) { dirtyRect.setEmpty(); deferredUpdateScheduled = false; - renderNode = NULL; + renderNode = nullptr; } void Layer::postDecStrong() { diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 2d6a727..3b4f293 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 3216cd2..60d4f4f 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -33,7 +33,7 @@ namespace uirenderer { LayerCache::LayerCache(): mSize(0), mMaxSize(MB(DEFAULT_LAYER_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting layer cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { @@ -80,13 +80,11 @@ 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); + layer->decStrong(nullptr); } } @@ -99,7 +97,7 @@ void LayerCache::clear() { } Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uint32_t height) { - Layer* layer = NULL; + Layer* layer = nullptr; LayerEntry entry(width, height); ssize_t index = mCache.indexOf(entry); @@ -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 81810ac..7d17b9b 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 83f9c6a..6ad1b19 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; @@ -131,7 +130,7 @@ void LayerRenderer::generateMesh() { if (mLayer->region.isRect() || mLayer->region.isEmpty()) { if (mLayer->mesh) { delete[] mLayer->mesh; - mLayer->mesh = NULL; + mLayer->mesh = nullptr; mLayer->meshElementCount = 0; } @@ -152,7 +151,7 @@ void LayerRenderer::generateMesh() { if (mLayer->mesh && mLayer->meshElementCount < elementCount) { delete[] mLayer->mesh; - mLayer->mesh = NULL; + mLayer->mesh = nullptr; } if (!mLayer->mesh) { @@ -193,14 +192,14 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width GLuint fbo = caches.fboCache.get(); if (!fbo) { ALOGW("Could not obtain an FBO"); - return NULL; + return nullptr; } caches.activeTexture(0); Layer* layer = caches.layerCache.get(renderState, width, height); if (!layer) { ALOGW("Could not obtain a layer"); - return NULL; + return nullptr; } // We first obtain a layer before comparing against the max texture size @@ -213,9 +212,9 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width // Creating a new layer always increment its refcount by 1, this allows // us to destroy the layer object if one was created for us - layer->decStrong(0); + layer->decStrong(nullptr); - return NULL; + return nullptr; } layer->setFbo(fbo); @@ -223,7 +222,7 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width layer->texCoords.set(0.0f, height / float(layer->getHeight()), width / float(layer->getWidth()), 0.0f); layer->setAlpha(255, SkXfermode::kSrcOver_Mode); - layer->setColorFilter(NULL); + layer->setColorFilter(nullptr); layer->setDirty(true); layer->region.clear(); @@ -241,8 +240,8 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width if (glGetError() != GL_NO_ERROR) { ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height); renderState.bindFramebuffer(previousFbo); - layer->decStrong(0); - return NULL; + layer->decStrong(nullptr); + return nullptr; } } @@ -317,7 +316,7 @@ void LayerRenderer::destroyLayer(Layer* layer) { if (!Caches::getInstance().layerCache.put(layer)) { LAYER_RENDERER_LOGD(" Destroyed!"); - layer->decStrong(0); + layer->decStrong(nullptr); } else { LAYER_RENDERER_LOGD(" Cached!"); #if DEBUG_LAYER_RENDERER @@ -424,7 +423,7 @@ bool LayerRenderer::copyLayer(RenderState& renderState, Layer* layer, SkBitmap* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, format, bitmap->width(), bitmap->height(), - 0, format, type, NULL); + 0, format, type, nullptr); if ((error = glGetError()) != GL_NO_ERROR) goto error; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 4d8620b..5e1e835 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -49,10 +49,11 @@ public: LayerRenderer(RenderState& renderState, Layer* layer); 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 onViewportInitialized() override { /* do nothing */ } + virtual void prepareDirty(float left, float top, float right, float bottom, + bool opaque) override; + virtual void clear(float left, float top, float right, float bottom, bool opaque) override; + virtual bool finish() override; static Layer* createTextureLayer(RenderState& renderState); static Layer* createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height); @@ -65,11 +66,11 @@ public: static void flushLayer(RenderState& renderState, Layer* layer); protected: - virtual void ensureStencilBuffer(); - virtual bool hasLayer() const; - virtual Region* getRegion() const; - virtual GLuint getTargetFbo() const; - virtual bool suppressErrorChecks() const; + virtual void ensureStencilBuffer() override; + virtual bool hasLayer() const override; + virtual Region* getRegion() const override; + virtual GLuint onGetTargetFbo() const override; + virtual bool suppressErrorChecks() const override; private: void generateMesh(); diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 1c5c578..a760135 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 355a31f..3c8fb8b 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -36,15 +36,19 @@ #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/PaintUtils.h" +#include "utils/TraceUtils.h" #if DEBUG_DETAILED_EVENTS #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__) @@ -130,13 +134,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 +193,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 +219,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 +236,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 +245,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 +254,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 +311,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 +338,8 @@ void OpenGLRenderer::finish() { } mFrameStarted = false; + + return reportAndClearDirty(); } void OpenGLRenderer::resumeAfterLayer() { @@ -349,10 +351,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 +373,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 +386,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 +404,6 @@ void OpenGLRenderer::eventMarkDEBUG(const char* fmt, ...) const { va_end(ap); eventMark(buf); -#else - (void)fmt; #endif } @@ -425,11 +425,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 +505,7 @@ void OpenGLRenderer::updateLayers() { if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); } endMark(); } @@ -522,7 +522,7 @@ void OpenGLRenderer::flushLayers() { } mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); endMark(); } @@ -604,9 +604,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 +619,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 +653,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 +673,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 +737,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 +749,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 +769,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 +788,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 +797,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 +808,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 +861,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 +906,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 +914,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 +1014,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 +1034,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 +1050,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 +1089,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 +1170,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 +1178,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 +1249,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 +1264,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 +1277,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 +1292,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 +1319,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 +1328,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 +1381,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 +1400,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 +1414,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 +1455,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 +1524,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 +1556,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 +1635,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; } } @@ -1677,8 +1668,10 @@ void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) { // argb=1,0,0,0 accountForClear(mode); // TODO: check shader blending, once we have shader drawing support for layers. - bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f || - (mColorSet && mColorA < 1.0f) || isBlendedColorFilter(layer->getColorFilter()); + bool blend = layer->isBlend() + || getLayerAlpha(layer) < 1.0f + || (mColorSet && mColorA < 1.0f) + || PaintUtils::isBlendedColorFilter(layer->getColorFilter()); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1689,7 +1682,7 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw accountForClear(mode); blend |= (mColorSet && mColorA < 1.0f) || (getShader(paint) && !getShader(paint)->isOpaque()) || - isBlendedColorFilter(getColorFilter(paint)); + PaintUtils::isBlendedColorFilter(getColorFilter(paint)); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1697,7 +1690,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 +1718,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 +1742,7 @@ void OpenGLRenderer::setupDrawPureColorUniforms() { } void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform) { - if (shader == NULL) { + if (shader == nullptr) { return; } @@ -1766,7 +1760,7 @@ void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignore } void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { - if (NULL == filter) { + if (nullptr == filter) { return; } @@ -1814,7 +1808,7 @@ void OpenGLRenderer::setupDrawTextGammaUniforms() { void OpenGLRenderer::setupDrawSimpleMesh() { bool force = mCaches.bindMeshBuffer(); - mCaches.bindPositionVertexPointer(force, 0); + mCaches.bindPositionVertexPointer(force, nullptr); mCaches.unbindIndicesBuffer(); } @@ -1903,39 +1897,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 +1949,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 +1958,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 +1984,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 +2003,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 +2021,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 +2040,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 +2091,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 +2135,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 +2222,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 +2290,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 +2298,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 +2312,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 +2333,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 +2364,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 +2392,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 +2410,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 +2420,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 +2437,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 +2459,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 +2472,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; + || PaintUtils::paintWillNotDraw(*p)) { + 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; + || PaintUtils::paintWillNotDraw(*p)) { + 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; + || PaintUtils::paintWillNotDraw(*p)) { + 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; + || PaintUtils::paintWillNotDraw(*p)) { + 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 +2568,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; + || PaintUtils::paintWillNotDraw(*p)) { + 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 +2635,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 +2653,26 @@ 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; - return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; + float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha; + return MathUtils::isZero(alpha) + && PaintUtils::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 +2704,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 +2720,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 +2744,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 +2864,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 +2876,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 +2891,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 +2912,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 +2959,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 +3015,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 +3042,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 +3089,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 +3144,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 +3181,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 +3222,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 +3245,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 +3277,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 +3360,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 +3368,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 +3396,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 +3446,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 +3462,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 5eee2e2..9d9b3d2 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,10 @@ #include "Rect.h" #include "Renderer.h" #include "Snapshot.h" -#include "StatefulBaseRenderer.h" #include "UvMapper.h" #include "Vertex.h" #include "Caches.h" -#include "CanvasProperty.h" +#include "utils/PaintUtils.h" class SkShader; @@ -63,20 +63,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 +117,7 @@ enum ModelViewMode { /** * OpenGL Renderer implementation. */ -class OpenGLRenderer : public StatefulBaseRenderer { +class OpenGLRenderer : public Renderer, public CanvasStateClient { public: OpenGLRenderer(RenderState& renderState); virtual ~OpenGLRenderer(); @@ -132,11 +126,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 +141,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 +153,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 +224,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,14 +267,15 @@ 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); } static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) { if (!paint) return SkXfermode::kSrcOver_Mode; - return getXfermode(paint->getXfermode()); + return PaintUtils::getXfermode(paint->getXfermode()); } static inline int getAlphaDirect(const SkPaint* paint) { @@ -312,7 +305,7 @@ public: } static inline bool hasTextShadow(const SkPaint* paint) { - return getTextShadow(paint, NULL); + return getTextShadow(paint, nullptr); } /** @@ -334,18 +327,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 +408,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 +434,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 +460,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 +502,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 +510,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 +522,8 @@ protected: inline RenderState& renderState() { return mRenderState; } + CanvasState mState; + private: /** * Discards the content of the framebuffer if supported by the driver. @@ -514,8 +559,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 +672,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 +686,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 +706,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 +723,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 +910,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 +937,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 +974,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 +987,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 +1030,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 +1059,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 +1070,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 6dacd5e..5e9b213 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 442e9ba..8a4d65b 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(); @@ -75,10 +71,10 @@ TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeig uint32_t yCount = patch->numYDivs; uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 4; - if (maxVertices == 0) return NULL; + if (maxVertices == 0) return nullptr; - 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 1ba045d..ea8c8c2 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 2f2debc..eb88bc0 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" @@ -32,9 +33,9 @@ namespace uirenderer { PatchCache::PatchCache(): mSize(0), mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity), - mMeshBuffer(0), mFreeBlocks(NULL), mGenerationId(0) { + mMeshBuffer(0), mFreeBlocks(nullptr), mGenerationId(0) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_PATCH_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_PATCH_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting patch cache size to %skB", property); mMaxSize = KB(atoi(property)); } else { @@ -104,7 +105,7 @@ void PatchCache::clearCache() { delete block; block = next; } - mFreeBlocks = NULL; + mFreeBlocks = nullptr; } void PatchCache::remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch) { @@ -124,11 +125,11 @@ void PatchCache::removeDeferred(Res_png_9patch* patch) { size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { if (patch == mGarbage[i]) { - patch = NULL; + patch = nullptr; break; } } - LOG_ALWAYS_FATAL_IF(patch == NULL); + LOG_ALWAYS_FATAL_IF(patch == nullptr); mGarbage.push(patch); } @@ -174,7 +175,7 @@ void PatchCache::clearGarbage() { } void PatchCache::createVertexBuffer() { - glBufferData(GL_ARRAY_BUFFER, mMaxSize, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mMaxSize, nullptr, GL_DYNAMIC_DRAW); mSize = 0; mFreeBlocks = new BufferBlock(0, mMaxSize); mGenerationId++; @@ -196,7 +197,7 @@ void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) { } // Find a block where we can fit the mesh - BufferBlock* previous = NULL; + BufferBlock* previous = nullptr; BufferBlock* block = mFreeBlocks; while (block) { // The mesh fits @@ -212,7 +213,7 @@ void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) { if (!block) { clearCache(); createVertexBuffer(); - previous = NULL; + previous = nullptr; block = mFreeBlocks; } diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 9f2c9a5..4cb5338 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.cpp b/libs/hwui/PathCache.cpp index 80f9c2f..c564b87 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -48,7 +48,7 @@ PathDescription::PathDescription(): style(SkPaint::kFill_Style), miter(4.0f), strokeWidth(1.0f), - pathEffect(NULL) { + pathEffect(nullptr) { memset(&shape, 0, sizeof(Shape)); } @@ -81,7 +81,7 @@ hash_t PathDescription::hash() const { bool PathCache::canDrawAsConvexPath(SkPath* path, const SkPaint* paint) { // NOTE: This should only be used after PathTessellator handles joins properly - return paint->getPathEffect() == NULL && path->getConvexity() == SkPath::kConvex_Convexity; + return paint->getPathEffect() == nullptr && path->getConvexity() == SkPath::kConvex_Convexity; } void PathCache::computePathBounds(const SkPath* path, const SkPaint* paint, @@ -114,9 +114,9 @@ static void initPaint(SkPaint& paint) { // will be applied later when compositing the alpha8 texture paint.setColor(SK_ColorBLACK); paint.setAlpha(255); - paint.setColorFilter(NULL); - paint.setMaskFilter(NULL); - paint.setShader(NULL); + paint.setColorFilter(nullptr); + paint.setMaskFilter(nullptr); + paint.setShader(nullptr); SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); SkSafeUnref(paint.setXfermode(mode)); } @@ -153,7 +153,7 @@ PathCache::PathCache(): mCache(LruCache<PathDescription, PathTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_PATH_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_PATH_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting %s cache size to %sMB", name, property); setMaxSize(MB(atof(property))); } else { @@ -211,7 +211,7 @@ void PathCache::removeTexture(PathTexture* texture) { // If there is a pending task we must wait for it to return // before attempting our cleanup const sp<Task<SkBitmap*> >& task = texture->task(); - if (task != NULL) { + if (task != nullptr) { task->getResult(); texture->clearTask(); } else { @@ -261,7 +261,7 @@ PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath *p uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); - if (!checkTextureSize(width, height)) return NULL; + if (!checkTextureSize(width, height)) return nullptr; purgeCache(width, height); @@ -355,7 +355,7 @@ void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) { } else { texture->width = 0; texture->height = 0; - t->setResult(NULL); + t->setResult(nullptr); } } @@ -430,7 +430,7 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) { // A bitmap is attached to the texture, this means we need to // upload it as a GL texture const sp<Task<SkBitmap*> >& task = texture->task(); - if (task != NULL) { + if (task != nullptr) { // But we must first wait for the worker thread to be done // producing the bitmap, so let's wait SkBitmap* bitmap = task->getResult(); @@ -440,7 +440,7 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) { } else { ALOGW("Path too large to be rendered into a texture"); texture->clearTask(); - texture = NULL; + texture = nullptr; mCache.remove(entry); } } else if (path->getGenerationID() != texture->generation) { @@ -490,7 +490,7 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) { // be enforced. mCache.put(entry, texture); - if (mProcessor == NULL) { + if (mProcessor == nullptr) { mProcessor = new PathProcessor(Caches::getInstance()); } mProcessor->add(task); diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index bc34188..ecd3712 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 9f7dd50..ceec4fc 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 5b642b9..efa271e 100644 --- a/libs/hwui/PixelBuffer.cpp +++ b/libs/hwui/PixelBuffer.cpp @@ -34,33 +34,28 @@ 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(); + uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override; + void unmap() override; - uint8_t* getMappedPointer() const; + uint8_t* getMappedPointer() const override; - void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); + void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override; 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]); } /////////////////////////////////////////////////////////////////////////////// @@ -85,12 +80,12 @@ public: GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); ~GpuPixelBuffer(); - uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); - void unmap(); + uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override; + void unmap() override; - uint8_t* getMappedPointer() const; + uint8_t* getMappedPointer() const override; - void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); + void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override; private: GLuint mBuffer; @@ -98,11 +93,13 @@ private: Caches& mCaches; }; -GpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): - PixelBuffer(format, width, height), mMappedPointer(0), mCaches(Caches::getInstance()) { +GpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height) + : PixelBuffer(format, width, height) + , mMappedPointer(nullptr) + , mCaches(Caches::getInstance()) { glGenBuffers(1, &mBuffer); mCaches.bindPixelBuffer(mBuffer); - glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), nullptr, GL_DYNAMIC_DRAW); mCaches.unbindPixelBuffer(); } @@ -138,7 +135,7 @@ void GpuPixelBuffer::unmap() { } } mAccessMode = kAccessMode_None; - mMappedPointer = NULL; + mMappedPointer = nullptr; } } diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index e6fd2dc..fb07dfa 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -64,7 +64,7 @@ Program::Program(const ProgramDescription& description, const char* vertex, cons glGetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { GLchar log[infoLen]; - glGetProgramInfoLog(mProgramId, infoLen, 0, &log[0]); + glGetProgramInfoLog(mProgramId, infoLen, nullptr, &log[0]); ALOGE("%s", log); } LOG_ALWAYS_FATAL("Error while linking shaders"); @@ -135,7 +135,7 @@ GLuint Program::buildShader(const char* source, GLenum type) { ATRACE_NAME("Build GL Shader"); GLuint shader = glCreateShader(type); - glShaderSource(shader, 1, &source, 0); + glShaderSource(shader, 1, &source, nullptr); glCompileShader(shader); GLint status; @@ -145,7 +145,7 @@ GLuint Program::buildShader(const char* source, GLenum type) { // Some drivers return wrong values for GL_INFO_LOG_LENGTH // use a fixed size instead GLchar log[512]; - glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); + glGetShaderInfoLog(shader, sizeof(log), nullptr, &log[0]); LOG_ALWAYS_FATAL("Shader info log: %s", log); return 0; } diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index fc7d134..d05b331 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 62835e0..3bbd520 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); - Program* program = NULL; - if (index < 0) { + auto iter = mCache.find(key); + Program* program = nullptr; + 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 38f6f99..30fa0df 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 7b9459a..a0312e1 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 13265a9..b046b6f 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.cpp b/libs/hwui/RenderBufferCache.cpp index 830a13a..0380c51 100644 --- a/libs/hwui/RenderBufferCache.cpp +++ b/libs/hwui/RenderBufferCache.cpp @@ -42,7 +42,7 @@ namespace uirenderer { RenderBufferCache::RenderBufferCache(): mSize(0), mMaxSize(MB(DEFAULT_RENDER_BUFFER_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_RENDER_BUFFER_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_RENDER_BUFFER_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting render buffer cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { @@ -108,7 +108,7 @@ void RenderBufferCache::clear() { } RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) { - RenderBuffer* buffer = NULL; + RenderBuffer* buffer = nullptr; RenderBufferEntry entry(format, width, height); ssize_t index = mCache.indexOf(entry); diff --git a/libs/hwui/RenderBufferCache.h b/libs/hwui/RenderBufferCache.h index af8060f..6c668b0 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 c993556..5a7ea40 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" @@ -77,10 +78,10 @@ void RenderNode::debugDumpLayers(const char* prefix) { RenderNode::RenderNode() : mDirtyPropertyFields(0) , mNeedsDisplayListDataSync(false) - , mDisplayListData(0) - , mStagingDisplayListData(0) + , mDisplayListData(nullptr) + , mStagingDisplayListData(nullptr) , mAnimatorManager(*this) - , mLayer(0) + , mLayer(nullptr) , mParentCount(0) { } @@ -90,7 +91,7 @@ RenderNode::~RenderNode() { if (mLayer) { ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer); mLayer->postDecStrong(); - mLayer = 0; + mLayer = nullptr; } } @@ -109,7 +110,7 @@ void RenderNode::output(uint32_t level) { getName(), (properties().hasShadow() ? ", casting shadow" : ""), (isRenderable() ? "" : ", empty"), - (mLayer != NULL ? ", on HW Layer" : "")); + (mLayer != nullptr ? ", on HW Layer" : "")); ALOGD("%*s%s %d", level * 2, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); @@ -181,7 +182,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { if (CC_LIKELY(layerType != kLayerTypeRenderLayer) || CC_UNLIKELY(!isRenderable())) { if (CC_UNLIKELY(mLayer)) { LayerRenderer::destroyLayer(mLayer); - mLayer = NULL; + mLayer = nullptr; } return; } @@ -195,7 +196,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) { if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { LayerRenderer::destroyLayer(mLayer); - mLayer = 0; + mLayer = nullptr; } damageSelf(info); transformUpdateNeeded = true; @@ -222,7 +223,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { } if (dirty.intersect(0, 0, getWidth(), getHeight())) { - dirty.roundOut(); + dirty.roundOut(&dirty); mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom); } // This is not inside the above if because we may have called @@ -310,10 +311,10 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) { Caches::getInstance().registerFunctors(mStagingDisplayListData->functors.size()); } mDisplayListData = mStagingDisplayListData; - mStagingDisplayListData = NULL; + mStagingDisplayListData = nullptr; if (mDisplayListData) { for (size_t i = 0; i < mDisplayListData->functors.size(); i++) { - (*mDisplayListData->functors[i])(DrawGlInfo::kModeSync, NULL); + (*mDisplayListData->functors[i])(DrawGlInfo::kModeSync, nullptr); } } damageSelf(info); @@ -330,7 +331,7 @@ void RenderNode::deleteDisplayListData() { } } delete mDisplayListData; - mDisplayListData = NULL; + mDisplayListData = nullptr; } void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) { @@ -358,7 +359,7 @@ void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) { void RenderNode::destroyHardwareResources() { if (mLayer) { LayerRenderer::destroyLayer(mLayer); - mLayer = NULL; + mLayer = nullptr; } if (mDisplayListData) { for (size_t i = 0; i < mDisplayListData->children().size(); i++) { @@ -516,7 +517,7 @@ void RenderNode::computeOrdering() { // TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that // transform properties are applied correctly to top level children - if (mDisplayListData == NULL) return; + if (mDisplayListData == nullptr) return; for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) { DrawRenderNodeOp* childOp = mDisplayListData->children()[i]; childOp->mRenderNode->computeOrderingImpl(childOp, @@ -530,7 +531,7 @@ void RenderNode::computeOrderingImpl( Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, const mat4* transformFromProjectionSurface) { mProjectedNodes.clear(); - if (mDisplayListData == NULL || mDisplayListData->isEmpty()) return; + if (mDisplayListData == nullptr || mDisplayListData->isEmpty()) return; // TODO: should avoid this calculation in most cases // TODO: just calculate single matrix, down to all leaf composited elements @@ -554,9 +555,9 @@ void RenderNode::computeOrderingImpl( DrawRenderNodeOp* childOp = mDisplayListData->children()[i]; RenderNode* child = childOp->mRenderNode; - const SkPath* projectionOutline = NULL; - Vector<DrawRenderNodeOp*>* projectionChildren = NULL; - const mat4* projectionTransform = NULL; + const SkPath* projectionOutline = nullptr; + Vector<DrawRenderNodeOp*>* projectionChildren = nullptr; + const mat4* projectionTransform = nullptr; if (isProjectionReceiver && !child->properties().getProjectBackwards()) { // if receiving projections, collect projecting descendent @@ -682,7 +683,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& // holds temporary SkPath to store the result of intersections - SkPath* frameAllocatedPath = NULL; + SkPath* frameAllocatedPath = nullptr; const SkPath* outlinePath = casterOutlinePath; // intersect the outline with the reveal clip, if present @@ -809,9 +810,9 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& // If the projection reciever has an outline, we mask each of the projected rendernodes to it // Either with clipRect, or special saveLayer masking - if (projectionReceiverOutline != NULL) { + if (projectionReceiverOutline != nullptr) { const SkRect& outlineBounds = projectionReceiverOutline->getBounds(); - if (projectionReceiverOutline->isRect(NULL)) { + if (projectionReceiverOutline->isRect(nullptr)) { // mask to the rect outline simply with clipRect ClipRectOp* clipOp = new (alloc) ClipRectOp( outlineBounds.left(), outlineBounds.top(), @@ -846,7 +847,7 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& renderer.restoreToCount(restoreTo); } - if (projectionReceiverOutline != NULL) { + if (projectionReceiverOutline != nullptr) { handler(new (alloc) RestoreToCountOp(restoreTo), PROPERTY_SAVECOUNT, properties().getClipToBounds()); } @@ -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 2ce7cb7..bbe53ff 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.cpp b/libs/hwui/RenderProperties.cpp index 250cadc..bb6d087 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -35,7 +35,7 @@ namespace uirenderer { LayerProperties::LayerProperties() : mType(kLayerTypeNone) - , mColorFilter(NULL) { + , mColorFilter(nullptr) { reset(); } @@ -45,7 +45,7 @@ LayerProperties::~LayerProperties() { void LayerProperties::reset() { mOpaque = false; - setFromPaint(NULL); + setFromPaint(nullptr); } bool LayerProperties::setColorFilter(SkColorFilter* filter) { @@ -61,7 +61,7 @@ bool LayerProperties::setFromPaint(const SkPaint* paint) { OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); changed |= setAlpha(static_cast<uint8_t>(alpha)); changed |= setXferMode(mode); - changed |= setColorFilter(paint ? paint->getColorFilter() : NULL); + changed |= setColorFilter(paint ? paint->getColorFilter() : nullptr); return changed; } @@ -92,7 +92,7 @@ RenderProperties::PrimitiveFields::PrimitiveFields() } RenderProperties::ComputedFields::ComputedFields() - : mTransformMatrix(NULL) { + : mTransformMatrix(nullptr) { } RenderProperties::ComputedFields::~ComputedFields() { @@ -100,8 +100,8 @@ RenderProperties::ComputedFields::~ComputedFields() { } RenderProperties::RenderProperties() - : mStaticMatrix(NULL) - , mAnimationMatrix(NULL) { + : mStaticMatrix(nullptr) + , mAnimationMatrix(nullptr) { } RenderProperties::~RenderProperties() { diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 31c4f22..f0e22d6 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.cpp b/libs/hwui/RenderState.cpp index d1f5f4e..45a97fb 100644 --- a/libs/hwui/RenderState.cpp +++ b/libs/hwui/RenderState.cpp @@ -23,7 +23,7 @@ namespace uirenderer { RenderState::RenderState(renderthread::RenderThread& thread) : mRenderThread(thread) - , mCaches(NULL) + , mCaches(nullptr) , mViewportWidth(0) , mViewportHeight(0) , mFramebuffer(0) { @@ -105,7 +105,7 @@ void RenderState::interruptForFunctorInvoke() { if (mCaches->currentProgram) { if (mCaches->currentProgram->isInUse()) { mCaches->currentProgram->remove(); - mCaches->currentProgram = NULL; + mCaches->currentProgram = nullptr; } } mCaches->resetActiveTexture(); @@ -165,9 +165,9 @@ class DecStrongTask : public renderthread::RenderTask { public: DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} - virtual void run() { - mObject->decStrong(0); - mObject = 0; + virtual void run() override { + mObject->decStrong(nullptr); + mObject = nullptr; delete this; } diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h index 1ecfb1c..629fe0d 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 3159d1e..3240bbc 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; @@ -56,40 +57,6 @@ class ANDROID_API Renderer { public: virtual ~Renderer() {} - /** - * Safely retrieves the mode from the specified xfermode. If the specified - * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode. - */ - static inline SkXfermode::Mode getXfermode(SkXfermode* mode) { - SkXfermode::Mode resultMode; - if (!SkXfermode::AsMode(mode, &resultMode)) { - resultMode = SkXfermode::kSrcOver_Mode; - } - return resultMode; - } - - // TODO: move to a method on android:Paint - static inline bool paintWillNotDraw(const SkPaint& paint) { - return paint.getAlpha() == 0 - && !paint.getColorFilter() - && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; - } - - // TODO: move to a method on android:Paint - static inline bool paintWillNotDrawText(const SkPaint& paint) { - return paint.getAlpha() == 0 - && paint.getLooper() == NULL - && !paint.getColorFilter() - && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; - } - - static bool isBlendedColorFilter(const SkColorFilter* filter) { - if (filter == NULL) { - return false; - } - return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; - } - // ---------------------------------------------------------------------------- // Frame state operations // ---------------------------------------------------------------------------- @@ -111,7 +78,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 +94,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 +142,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 31bd637..45c27c2 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 { @@ -81,8 +79,8 @@ void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) { void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) { ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL || mCache->size() == 0) { + ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr; + if (ref == nullptr || mCache->size() == 0) { ref = new ResourceReference(resourceType); mCache->add(resource, ref); } @@ -120,8 +118,8 @@ void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) { void ResourceCache::decrementRefcountLocked(void* resource) { ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL) { + ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr; + if (ref == nullptr) { // Should not get here - shouldn't get a call to decrement if we're not yet tracking it return; } @@ -150,8 +148,8 @@ void ResourceCache::destructor(SkPath* resource) { void ResourceCache::destructorLocked(SkPath* resource) { ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL) { + ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr; + if (ref == nullptr) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().pathCache.removeDeferred(resource); @@ -173,8 +171,8 @@ void ResourceCache::destructor(const SkBitmap* resource) { void ResourceCache::destructorLocked(const SkBitmap* resource) { ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL) { + ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr; + if (ref == nullptr) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().textureCache.releaseTexture(resource); @@ -195,8 +193,8 @@ void ResourceCache::destructor(Res_png_9patch* resource) { void ResourceCache::destructorLocked(Res_png_9patch* resource) { ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL) { + ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr; + if (ref == nullptr) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().patchCache.removeDeferred(resource); @@ -233,11 +231,11 @@ bool ResourceCache::recycleLocked(SkBitmap* resource) { Caches::getInstance().textureCache.releaseTexture(resource); } // not tracking this resource; just recycle the pixel data - resource->setPixels(NULL, NULL); + resource->setPixels(nullptr, nullptr); return true; } ResourceReference* ref = mCache->valueAt(index); - if (ref == NULL) { + if (ref == nullptr) { // Should not get here - shouldn't get a call to recycle if we're not yet tracking it return true; } @@ -260,7 +258,7 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource if (Caches::hasInstance()) { Caches::getInstance().textureCache.releaseTexture(bitmap); } - bitmap->setPixels(NULL, NULL); + bitmap->setPixels(nullptr, nullptr); } if (ref->destroyed) { switch (ref->resourceType) { diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index f12f2a4..a252f6c 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 a9600f1..0084a8e 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.cpp b/libs/hwui/ShadowTessellator.cpp index 93d4b31..f8917e3 100644 --- a/libs/hwui/ShadowTessellator.cpp +++ b/libs/hwui/ShadowTessellator.cpp @@ -193,7 +193,7 @@ Vector2 ShadowTessellator::calculateNormal(const Vector2& p1, const Vector2& p2) * @param len the number of points of the polygon */ bool ShadowTessellator::isClockwise(const Vector2* polygon, int len) { - if (len < 2 || polygon == NULL) { + if (len < 2 || polygon == nullptr) { return true; } double sum = 0; diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h index 8f19b5c..16ad91d 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 c672bc4..2c09344 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" @@ -86,7 +87,7 @@ static bool bitmapAndGradient(SkiaShaderType type1, SkiaShaderType type2) { SkiaShaderType SkiaShader::getType(const SkShader& shader) { // First check for a gradient shader. - switch (shader.asAGradient(NULL)) { + switch (shader.asAGradient(nullptr)) { case SkShader::kNone_GradientType: // Not a gradient shader. Fall through to check for other types. break; @@ -100,7 +101,7 @@ SkiaShaderType SkiaShader::getType(const SkShader& shader) { } // The shader is not a gradient. Check for a bitmap shader. - if (shader.asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) { + if (shader.asABitmap(nullptr, nullptr, nullptr) == SkShader::kDefault_BitmapType) { return kBitmap_SkiaShaderType; } @@ -118,7 +119,7 @@ SkiaShaderType SkiaShader::getType(const SkShader& shader) { return kCompose_SkiaShaderType; } - if (shader.asACustomShader(NULL)) { + if (shader.asACustomShader(nullptr)) { return kLayer_SkiaShaderType; } @@ -254,17 +255,17 @@ void SkiaBitmapShader::describe(Caches* caches, ProgramDescription& description, const Extensions& extensions, const SkShader& shader) { SkBitmap bitmap; SkShader::TileMode xy[2]; - if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { + if (shader.asABitmap(&bitmap, nullptr, xy) != SkShader::kDefault_BitmapType) { LOG_ALWAYS_FATAL("SkiaBitmapShader::describe called with a different kind of shader!"); } - bitmapShaderHelper(caches, &description, NULL, extensions, bitmap, xy); + bitmapShaderHelper(caches, &description, nullptr, extensions, bitmap, xy); } void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { SkBitmap bitmap; SkShader::TileMode xy[2]; - if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { + if (shader.asABitmap(&bitmap, nullptr, xy) != SkShader::kDefault_BitmapType) { LOG_ALWAYS_FATAL("SkiaBitmapShader::setupProgram called with a different kind of shader!"); } @@ -272,7 +273,7 @@ void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, Caches::getInstance().activeTexture(textureSlot); BitmapShaderInfo shaderInfo; - if (!bitmapShaderHelper(caches, NULL, &shaderInfo, extensions, bitmap, xy)) { + if (!bitmapShaderHelper(caches, nullptr, &shaderInfo, extensions, bitmap, xy)) { return; } @@ -342,8 +343,8 @@ void SkiaGradientShader::describe(Caches*, ProgramDescription& description, const Extensions& extensions, const SkShader& shader) { SkShader::GradientInfo gradInfo; gradInfo.fColorCount = 0; - gradInfo.fColors = NULL; - gradInfo.fColorOffsets = NULL; + gradInfo.fColors = nullptr; + gradInfo.fColorOffsets = nullptr; switch (shader.asAGradient(&gradInfo)) { case SkShader::kLinear_GradientType: diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 631305f..e110ca5 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/Snapshot.cpp b/libs/hwui/Snapshot.cpp index cf8229f..d4ca99e 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -29,16 +29,16 @@ namespace uirenderer { Snapshot::Snapshot() : flags(0) - , previous(NULL) - , layer(NULL) + , previous(nullptr) + , layer(nullptr) , fbo(0) , invisible(false) , empty(false) , alpha(1.0f) - , roundRectClipState(NULL) { + , roundRectClipState(nullptr) { transform = &mTransformRoot; clipRect = &mClipRectRoot; - region = NULL; + region = nullptr; clipRegion = &mClipRegionRoot; } @@ -80,7 +80,7 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags) flags |= Snapshot::kFlagFboTarget; region = s->region; } else { - region = NULL; + region = nullptr; } } diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 3046fd5..a03192a 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 @@ -331,7 +332,7 @@ bool SpotShadow::testPointInsidePolygon(const Vector2 testPoint, * @param len the number of points of the polygon */ void SpotShadow::makeClockwise(Vector2* polygon, int len) { - if (polygon == 0 || len == 0) { + if (polygon == nullptr || len == 0) { return; } if (!ShadowTessellator::isClockwise(polygon, len)) { diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h index e2d94f7..62a7e5d 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 fcd6060..0000000 --- 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.cpp b/libs/hwui/TessellationCache.cpp index 1e38f9e..4f028d5 100644 --- a/libs/hwui/TessellationCache.cpp +++ b/libs/hwui/TessellationCache.cpp @@ -76,7 +76,7 @@ void TessellationCache::Description::setupMatrixAndPaint(Matrix4* matrix, SkPain } TessellationCache::ShadowDescription::ShadowDescription() - : nodeKey(NULL) { + : nodeKey(nullptr) { memset(&matrixData, 0, 16 * sizeof(float)); } @@ -114,7 +114,7 @@ public: : TaskProcessor<VertexBuffer*>(&caches.tasks) {} ~TessellationProcessor() {} - virtual void onProcess(const sp<Task<VertexBuffer*> >& task) { + virtual void onProcess(const sp<Task<VertexBuffer*> >& task) override { TessellationTask* t = static_cast<TessellationTask*>(task.get()); ATRACE_NAME("shape tessellation"); VertexBuffer* buffer = t->tessellator(t->description); @@ -126,7 +126,7 @@ class TessellationCache::Buffer { public: Buffer(const sp<Task<VertexBuffer*> >& task) : mTask(task) - , mBuffer(NULL) { + , mBuffer(nullptr) { } ~Buffer() { @@ -146,9 +146,9 @@ public: private: void blockOnPrecache() { - if (mTask != NULL) { + if (mTask != nullptr) { mBuffer = mTask->getResult(); - LOG_ALWAYS_FATAL_IF(mBuffer == NULL, "Failed to precache"); + LOG_ALWAYS_FATAL_IF(mBuffer == nullptr, "Failed to precache"); mTask.clear(); } } @@ -278,7 +278,7 @@ public: : TaskProcessor<TessellationCache::vertexBuffer_pair_t*>(&caches.tasks) {} ~ShadowProcessor() {} - virtual void onProcess(const sp<Task<TessellationCache::vertexBuffer_pair_t*> >& task) { + virtual void onProcess(const sp<Task<TessellationCache::vertexBuffer_pair_t*> >& task) override { ShadowTask* t = static_cast<ShadowTask*>(task.get()); ATRACE_NAME("shadow tessellation"); @@ -302,7 +302,7 @@ TessellationCache::TessellationCache() , mCache(LruCache<Description, Buffer*>::kUnlimitedCapacity) , mShadowCache(LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*>::kUnlimitedCapacity) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_VERTEX_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_VERTEX_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting %s cache size to %sMB", name, property); setMaxSize(MB(atof(property))); } else { @@ -382,12 +382,12 @@ void TessellationCache::precacheShadows(const Matrix4* drawTransform, const Rect sp<ShadowTask> task = new ShadowTask(drawTransform, localClip, opaque, casterPerimeter, transformXY, transformZ, lightCenter, lightRadius); - if (mShadowProcessor == NULL) { + if (mShadowProcessor == nullptr) { mShadowProcessor = new ShadowProcessor(Caches::getInstance()); } mShadowProcessor->add(task); - task->incStrong(NULL); // not using sp<>s, so manually ref while in the cache + task->incStrong(nullptr); // not using sp<>s, so manually ref while in the cache mShadowCache.put(key, task.get()); } @@ -402,7 +402,7 @@ void TessellationCache::getShadowBuffers(const Matrix4* drawTransform, const Rec transformXY, transformZ, lightCenter, lightRadius); task = static_cast<ShadowTask*>(mShadowCache.get(key)); } - LOG_ALWAYS_FATAL_IF(task == NULL, "shadow not precached"); + LOG_ALWAYS_FATAL_IF(task == nullptr, "shadow not precached"); outBuffers = *(task->getResult()); } @@ -418,7 +418,7 @@ TessellationCache::Buffer* TessellationCache::getOrCreateBuffer( sp<TessellationTask> task = new TessellationTask(tessellator, entry); buffer = new Buffer(task); - if (mProcessor == NULL) { + if (mProcessor == nullptr) { mProcessor = new TessellationProcessor(Caches::getInstance()); } mProcessor->add(task); diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h index 7eca681..3efeaf6 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 96c09e6..4ec298d 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" @@ -99,7 +100,7 @@ TextDropShadowCache::TextDropShadowCache(): mCache(LruCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting drop shadow cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { @@ -181,7 +182,7 @@ ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* text, len, numGlyphs, radius, positions); if (!shadow.image) { - return NULL; + return nullptr; } Caches& caches = Caches::getInstance(); diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index 54b930b..caf089f 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/Texture.cpp b/libs/hwui/Texture.cpp index e783905..58fd972 100644 --- a/libs/hwui/Texture.cpp +++ b/libs/hwui/Texture.cpp @@ -25,14 +25,14 @@ namespace android { namespace uirenderer { Texture::Texture(): id(0), generation(0), blend(false), width(0), height(0), - cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL), isInUse(false), + cleanup(false), bitmapSize(0), mipMap(false), uvMapper(nullptr), isInUse(false), mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE), mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST), mFirstFilter(true), mFirstWrap(true), mCaches(Caches::getInstance()) { } Texture::Texture(Caches& caches): id(0), generation(0), blend(false), width(0), height(0), - cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL), isInUse(false), + cleanup(false), bitmapSize(0), mipMap(false), uvMapper(nullptr), isInUse(false), mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE), mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST), mFirstFilter(true), mFirstWrap(true), mCaches(caches) { diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 63454d8..7dc2480 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" @@ -40,16 +41,16 @@ namespace uirenderer { TextureCache::TextureCache(): mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)), - mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(0) { + mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(nullptr) { char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) { + if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting texture cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { INIT_LOGD(" Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE); } - if (property_get(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, property, NULL) > 0) { + if (property_get(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, property, nullptr) > 0) { float flushRate = atof(property); INIT_LOGD(" Setting texture cache flush rate to %.2f%%", flushRate * 100.0f); setFlushRate(flushRate); @@ -63,7 +64,7 @@ TextureCache::TextureCache(): TextureCache::TextureCache(uint32_t maxByteSize): mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity), - mSize(0), mMaxSize(maxByteSize), mAssetAtlas(0) { + mSize(0), mMaxSize(maxByteSize), mAssetAtlas(nullptr) { init(); } @@ -159,7 +160,7 @@ Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { if (!texture) { if (!canMakeTextureFromBitmap(bitmap)) { - return NULL; + return nullptr; } const uint32_t size = bitmap->rowBytes() * bitmap->height(); @@ -209,7 +210,7 @@ Texture* TextureCache::get(const SkBitmap* bitmap) { if (!texture) { if (!canMakeTextureFromBitmap(bitmap)) { - return NULL; + return nullptr; } const uint32_t size = bitmap->rowBytes() * bitmap->height(); @@ -351,7 +352,7 @@ void TextureCache::uploadLoFiTexture(bool resize, const SkBitmap* bitmap, rgbaBitmap.eraseColor(0); SkCanvas canvas(rgbaBitmap); - canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL); + canvas.drawBitmap(*bitmap, 0.0f, 0.0f, nullptr); uploadToTexture(resize, GL_RGBA, rgbaBitmap.rowBytesAsPixels(), rgbaBitmap.bytesPerPixel(), width, height, GL_UNSIGNED_BYTE, rgbaBitmap.getPixels()); diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index cf8d134..0e33e4c 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 ae6ea94..0799c6c 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; @@ -59,11 +59,11 @@ public: : mode(mode) , prepareTextures(mode == MODE_FULL) , runAnimations(true) - , damageAccumulator(NULL) + , damageAccumulator(nullptr) , renderState(renderState) - , renderer(NULL) - , errorHandler(NULL) - , canvasContext(NULL) + , renderer(nullptr) + , errorHandler(nullptr) + , canvasContext(nullptr) {} explicit TreeInfo(TraversalMode mode, const TreeInfo& clone) diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h index 4ff0b18..fe8a752 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 8c3a272..d81dd42 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 24ffb80..128e392 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" @@ -42,7 +43,7 @@ CacheBlock* CacheBlock::insertBlock(CacheBlock* head, CacheBlock* newBlock) { #endif CacheBlock* currBlock = head; - CacheBlock* prevBlock = NULL; + CacheBlock* prevBlock = nullptr; while (currBlock && currBlock->mY != TEXTURE_BORDER_SIZE) { if (newBlock->mWidth < currBlock->mWidth) { @@ -109,9 +110,9 @@ CacheBlock* CacheBlock::removeBlock(CacheBlock* head, CacheBlock* blockToRemove) /////////////////////////////////////////////////////////////////////////////// CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount) : - mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height), mFormat(format), + mTexture(nullptr), mTextureId(0), mWidth(width), mHeight(height), mFormat(format), mLinearFiltering(false), mDirty(false), mNumGlyphs(0), - mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount), + mMesh(nullptr), mCurrentQuad(0), mMaxQuadCount(maxQuadCount), mCaches(Caches::getInstance()) { mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE, mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE); @@ -130,7 +131,7 @@ CacheTexture::~CacheTexture() { void CacheTexture::reset() { // Delete existing cache blocks - while (mCacheBlocks != NULL) { + while (mCacheBlocks != nullptr) { CacheBlock* tmpBlock = mCacheBlocks; mCacheBlocks = mCacheBlocks->mNext; delete tmpBlock; @@ -153,7 +154,7 @@ void CacheTexture::releaseMesh() { void CacheTexture::releaseTexture() { if (mTexture) { delete mTexture; - mTexture = NULL; + mTexture = nullptr; } if (mTextureId) { mCaches.deleteTexture(mTextureId); @@ -192,7 +193,7 @@ void CacheTexture::allocateTexture() { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Initialize texture dimensions glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0, - mFormat, GL_UNSIGNED_BYTE, 0); + mFormat, GL_UNSIGNED_BYTE, nullptr); const GLenum filtering = getLinearFiltering() ? GL_LINEAR : GL_NEAREST; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h index 4cc4f22..5d3f959 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 6680a00..0642d59 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 e1a38dd..b07a3c8 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); } @@ -302,13 +298,13 @@ CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bo void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, const float* positions) { - render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, - 0, 0, NULL, positions); + render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, nullptr, + 0, 0, nullptr, positions); } void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, const SkPath* path, float hOffset, float vOffset) { - if (numGlyphs == 0 || text == NULL || len == 0) { + if (numGlyphs == 0 || text == nullptr || len == 0) { return; } @@ -358,18 +354,18 @@ void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32 void Font::measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds, const float* positions) { - if (bounds == NULL) { + if (bounds == nullptr) { ALOGE("No return rectangle provided to measure text"); return; } bounds->set(1e6, -1e6, -1e6, 1e6); - render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, positions); + render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions); } void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) { ATRACE_NAME("Precache Glyphs"); - if (numGlyphs == 0 || text == NULL) { + if (numGlyphs == 0 || text == nullptr) { return; } @@ -390,7 +386,7 @@ void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) { void Font::render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) { - if (numGlyphs == 0 || text == NULL || len == 0) { + if (numGlyphs == 0 || text == nullptr || len == 0) { return; } @@ -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 0f10464..3119d73 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 b7e1752..71ecba5 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -45,28 +45,27 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mBufferPreserved(false) , mSwapBehavior(kSwap_default) , mOpaque(!translucent) - , mCanvas(NULL) + , mCanvas(nullptr) , 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); } void CanvasContext::destroy() { stopDrawing(); - setSurface(NULL); + setSurface(nullptr); freePrefetechedLayers(); destroyHardwareResources(); mAnimationContext->destroy(); if (mCanvas) { delete mCanvas; - mCanvas = 0; + mCanvas = nullptr; } } @@ -96,7 +95,7 @@ void CanvasContext::setSurface(ANativeWindow* window) { void CanvasContext::swapBuffers() { if (CC_UNLIKELY(!mEglManager.swapBuffers(mEglSurface))) { - setSurface(NULL); + setSurface(nullptr); } mHaveNewSurface = false; } @@ -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(); @@ -275,19 +273,19 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) { mode = DrawGlInfo::kModeProcess; } - thread.renderState().invokeFunctor(functor, mode, NULL); + thread.renderState().invokeFunctor(functor, mode, nullptr); } void CanvasContext::markLayerInUse(RenderNode* node) { if (mPrefetechedLayers.erase(node)) { - node->decStrong(0); + node->decStrong(nullptr); } } static void destroyPrefetechedNode(RenderNode* node) { ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName()); node->destroyHardwareResources(); - node->decStrong(0); + node->decStrong(nullptr); } void CanvasContext::freePrefetechedLayers() { @@ -321,7 +319,7 @@ void CanvasContext::buildLayer(RenderNode* node) { mCanvas->markLayersAsBuildLayers(); mCanvas->flushLayerUpdates(); - node->incStrong(0); + node->incStrong(nullptr); mPrefetechedLayers.insert(node); } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 0cc2c7c..d3fbde8 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -80,7 +80,7 @@ public: void destroy(); // IFrameCallback, Chroreographer-driven frame callback entry point - virtual void doFrame(); + virtual void doFrame() override; void buildLayer(RenderNode* node); bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); @@ -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/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 97b31a9..4d8a469 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -32,8 +32,8 @@ namespace uirenderer { namespace renderthread { DrawFrameTask::DrawFrameTask() - : mRenderThread(NULL) - , mContext(NULL) + : mRenderThread(nullptr) + , mContext(nullptr) , mFrameTimeNanos(0) , mRecordDurationNanos(0) , mDensity(1.0f) // safe enough default diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index 28f6cb2..953f012 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -64,7 +64,7 @@ public: void setDensity(float density) { mDensity = density; } int drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos); - virtual void run(); + virtual void run() override; private: void postAndWait(); diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 8fb1b10..0aa0439 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" @@ -67,12 +68,12 @@ static bool load_dirty_regions_property() { EglManager::EglManager(RenderThread& thread) : mRenderThread(thread) , mEglDisplay(EGL_NO_DISPLAY) - , mEglConfig(0) + , mEglConfig(nullptr) , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mAllowPreserveBuffer(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) - , mAtlasMap(NULL) + , mAtlasMap(nullptr) , mAtlasMapSize(0) , mInFrame(false) { mCanSetPreserveBuffer = mAllowPreserveBuffer; @@ -193,7 +194,7 @@ void EglManager::usePBufferSurface() { EGLSurface EglManager::createSurface(EGLNativeWindowType window) { initialize(); - EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL); + EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, nullptr); LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, "Failed to create EGLSurface for window %p, eglErr = %s", (void*) window, egl_error_str()); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 36ba3a9..35f5512 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -60,7 +60,7 @@ CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent, RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory) : mRenderThread(RenderThread::getInstance()) - , mContext(0) { + , mContext(nullptr) { SETUP_TASK(createContext); args->translucent = translucent; args->rootRenderNode = rootRenderNode; @@ -76,15 +76,15 @@ RenderProxy::~RenderProxy() { CREATE_BRIDGE1(destroyContext, CanvasContext* context) { delete args->context; - return NULL; + return nullptr; } void RenderProxy::destroyContext() { if (mContext) { SETUP_TASK(destroyContext); args->context = mContext; - mContext = 0; - mDrawFrameTask.setContext(NULL, NULL); + mContext = nullptr; + mDrawFrameTask.setContext(nullptr, nullptr); // This is also a fence as we need to be certain that there are no // outstanding mDrawFrame tasks posted before it is destroyed postAndWait(task); @@ -93,7 +93,7 @@ void RenderProxy::destroyContext() { CREATE_BRIDGE2(setFrameInterval, RenderThread* thread, nsecs_t frameIntervalNanos) { args->thread->timeLord().setFrameInterval(args->frameIntervalNanos); - return NULL; + return nullptr; } void RenderProxy::setFrameInterval(nsecs_t frameIntervalNanos) { @@ -105,7 +105,7 @@ void RenderProxy::setFrameInterval(nsecs_t frameIntervalNanos) { CREATE_BRIDGE2(setSwapBehavior, CanvasContext* context, SwapBehavior swapBehavior) { args->context->setSwapBehavior(args->swapBehavior); - return NULL; + return nullptr; } void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) { @@ -145,7 +145,7 @@ bool RenderProxy::initialize(const sp<ANativeWindow>& window) { CREATE_BRIDGE2(updateSurface, CanvasContext* context, ANativeWindow* window) { args->context->updateSurface(args->window); - return NULL; + return nullptr; } void RenderProxy::updateSurface(const sp<ANativeWindow>& window) { @@ -171,7 +171,7 @@ CREATE_BRIDGE7(setup, CanvasContext* context, int width, int height, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { args->context->setup(args->width, args->height, args->lightCenter, args->lightRadius, args->ambientShadowAlpha, args->spotShadowAlpha); - return NULL; + return nullptr; } void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float lightRadius, @@ -189,7 +189,7 @@ void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) { args->context->setOpaque(args->opaque); - return NULL; + return nullptr; } void RenderProxy::setOpaque(bool opaque) { @@ -207,7 +207,7 @@ int RenderProxy::syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDuration CREATE_BRIDGE1(destroy, CanvasContext* context) { args->context->destroy(); - return NULL; + return nullptr; } void RenderProxy::destroy() { @@ -221,7 +221,7 @@ void RenderProxy::destroy() { CREATE_BRIDGE2(invokeFunctor, RenderThread* thread, Functor* functor) { CanvasContext::invokeFunctor(*args->thread, args->functor); - return NULL; + return nullptr; } void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) { @@ -242,7 +242,7 @@ void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) { CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) { args->context->runWithGlContext(args->task); - return NULL; + return nullptr; } void RenderProxy::runWithGlContext(RenderTask* gltask) { @@ -254,7 +254,7 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) { CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) { Layer* layer = args->context->createTextureLayer(); - if (!layer) return 0; + if (!layer) return nullptr; return new DeferredLayerUpdater(*args->thread, layer); } @@ -269,7 +269,7 @@ DeferredLayerUpdater* RenderProxy::createTextureLayer() { CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) { args->context->buildLayer(args->node); - return NULL; + return nullptr; } void RenderProxy::buildLayer(RenderNode* node) { @@ -303,7 +303,7 @@ void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) { CREATE_BRIDGE1(detachSurfaceTexture, DeferredLayerUpdater* layer) { args->layer->detachSurfaceTexture(); - return NULL; + return nullptr; } void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) { @@ -314,7 +314,7 @@ void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) { CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) { args->context->destroyHardwareResources(); - return NULL; + return nullptr; } void RenderProxy::destroyHardwareResources() { @@ -325,7 +325,7 @@ void RenderProxy::destroyHardwareResources() { CREATE_BRIDGE2(timMemory, RenderThread* thread, int level) { CanvasContext::trimMemory(*args->thread, args->level); - return NULL; + return nullptr; } void RenderProxy::trimMemory(int level) { @@ -339,16 +339,14 @@ void RenderProxy::trimMemory(int level) { } } -template <typename T> -void UNUSED(T) {} - - CREATE_BRIDGE0(fence) { // Intentionally empty - UNUSED(args); - return NULL; + return nullptr; } +template <typename T> +void UNUSED(T t) {} + void RenderProxy::fence() { SETUP_TASK(fence); UNUSED(args); @@ -357,7 +355,7 @@ void RenderProxy::fence() { CREATE_BRIDGE1(stopDrawing, CanvasContext* context) { args->context->stopDrawing(); - return NULL; + return nullptr; } void RenderProxy::stopDrawing() { @@ -368,7 +366,7 @@ void RenderProxy::stopDrawing() { CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) { args->context->notifyFramePending(); - return NULL; + return nullptr; } void RenderProxy::notifyFramePending() { @@ -379,7 +377,7 @@ void RenderProxy::notifyFramePending() { CREATE_BRIDGE2(dumpProfileInfo, CanvasContext* context, int fd) { args->context->profiler().dumpData(args->fd); - return NULL; + return nullptr; } void RenderProxy::dumpProfileInfo(int fd) { @@ -391,7 +389,7 @@ void RenderProxy::dumpProfileInfo(int fd) { CREATE_BRIDGE1(outputLogBuffer, int fd) { RenderNode::outputLogBuffer(args->fd); - return NULL; + return nullptr; } void RenderProxy::outputLogBuffer(int fd) { @@ -402,15 +400,15 @@ void RenderProxy::outputLogBuffer(int fd) { CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) { CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size); - args->buffer->decStrong(0); - return NULL; + args->buffer->decStrong(nullptr); + return nullptr; } void RenderProxy::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) { SETUP_TASK(setTextureAtlas); args->thread = &mRenderThread; args->buffer = buffer.get(); - args->buffer->incStrong(0); + args->buffer->incStrong(nullptr); args->map = map; args->size = size; post(task); diff --git a/libs/hwui/renderthread/RenderTask.cpp b/libs/hwui/renderthread/RenderTask.cpp index 13970ba..b14f580 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/renderthread/RenderTask.h b/libs/hwui/renderthread/RenderTask.h index 1554a16..89c3a7d 100644 --- a/libs/hwui/renderthread/RenderTask.h +++ b/libs/hwui/renderthread/RenderTask.h @@ -47,7 +47,7 @@ namespace renderthread { class ANDROID_API RenderTask { public: - ANDROID_API RenderTask() : mNext(0), mRunAt(0) {} + ANDROID_API RenderTask() : mNext(nullptr), mRunAt(0) {} ANDROID_API virtual ~RenderTask() {} ANDROID_API virtual void run() = 0; @@ -61,7 +61,7 @@ public: // Takes ownership of task, caller owns lock and signal SignalingRenderTask(RenderTask* task, Mutex* lock, Condition* signal) : mTask(task), mLock(lock), mSignal(signal) {} - virtual void run(); + virtual void run() override; private: RenderTask* mTask; @@ -74,12 +74,12 @@ typedef void* (*RunnableMethod)(void* data); class MethodInvokeRenderTask : public RenderTask { public: MethodInvokeRenderTask(RunnableMethod method) - : mMethod(method), mReturnPtr(0) {} + : mMethod(method), mReturnPtr(nullptr) {} void* payload() { return mData; } void setReturnPtr(void** retptr) { mReturnPtr = retptr; } - virtual void run() { + virtual void run() override { void* retval = mMethod(mData); if (mReturnPtr) { *mReturnPtr = retval; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 3e4e965..361a440 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -42,16 +42,16 @@ static const size_t EVENT_BUFFER_SIZE = 100; // Slight delay to give the UI time to push us a new frame before we replay static const nsecs_t DISPATCH_FRAME_CALLBACKS_DELAY = milliseconds_to_nanoseconds(4); -TaskQueue::TaskQueue() : mHead(0), mTail(0) {} +TaskQueue::TaskQueue() : mHead(nullptr), mTail(nullptr) {} RenderTask* TaskQueue::next() { RenderTask* ret = mHead; if (ret) { mHead = ret->mNext; if (!mHead) { - mTail = 0; + mTail = nullptr; } - ret->mNext = 0; + ret->mNext = nullptr; } return ret; } @@ -71,7 +71,7 @@ void TaskQueue::queue(RenderTask* task) { mTail = task; } else { // Need to find the proper insertion point - RenderTask* previous = 0; + RenderTask* previous = nullptr; RenderTask* next = mHead; while (next && next->mRunAt <= task->mRunAt) { previous = next; @@ -131,19 +131,19 @@ private: public: DispatchFrameCallbacks(RenderThread* rt) : mRenderThread(rt) {} - virtual void run() { + virtual void run() override { mRenderThread->dispatchFrameCallbacks(); } }; RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>() , mNextWakeup(LLONG_MAX) - , mDisplayEventReceiver(0) + , mDisplayEventReceiver(nullptr) , mVsyncRequested(false) , mFrameCallbackTaskPending(false) - , mFrameCallbackTask(0) - , mRenderState(NULL) - , mEglManager(NULL) { + , mFrameCallbackTask(nullptr) + , mRenderState(nullptr) + , mEglManager(nullptr) { mFrameCallbackTask = new DispatchFrameCallbacks(this); mLooper = new Looper(false); run("RenderThread"); @@ -342,7 +342,7 @@ RenderTask* RenderThread::nextTask(nsecs_t* nextWakeup) { if (next->mRunAt <= 0 || next->mRunAt <= systemTime(SYSTEM_TIME_MONOTONIC)) { next = mQueue.next(); } else { - next = 0; + next = nullptr; } } if (nextWakeup) { diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 99c2e15..8fc8ca5 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -90,7 +90,7 @@ public: EglManager& eglManager() { return *mEglManager; } protected: - virtual bool threadLoop(); + virtual bool threadLoop() override; private: friend class Singleton<RenderThread>; diff --git a/libs/hwui/tests/Android.mk b/libs/hwui/tests/Android.mk index 7bdce7f..2fff07d 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/TestContext.cpp b/libs/hwui/tests/TestContext.cpp index 35e402d..542bbae 100644 --- a/libs/hwui/tests/TestContext.cpp +++ b/libs/hwui/tests/TestContext.cpp @@ -16,30 +16,59 @@ #include "TestContext.h" -#include <gui/ISurfaceComposer.h> -#include <gui/SurfaceComposerClient.h> +namespace android { +namespace uirenderer { +namespace test { -using namespace android; +static const int IDENT_DISPLAYEVENT = 1; -DisplayInfo gDisplay; -sp<SurfaceComposerClient> gSession; - -void createTestEnvironment() { - gSession = new SurfaceComposerClient(); +static DisplayInfo getBuiltInDisplay() { + DisplayInfo display; sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); - status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &gDisplay); + ISurfaceComposer::eDisplayIdMain)); + status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display); LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n"); + return display; +} + +android::DisplayInfo gDisplay = getBuiltInDisplay(); + +TestContext::TestContext() { + mLooper = new Looper(true); + mSurfaceComposerClient = new SurfaceComposerClient(); + mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT, + Looper::EVENT_INPUT, nullptr, nullptr); } -sp<SurfaceControl> createWindow(int width, int height) { - sp<SurfaceControl> control = gSession->createSurface(String8("HwuiTest"), - width, height, PIXEL_FORMAT_RGBX_8888); +TestContext::~TestContext() {} + +sp<Surface> TestContext::surface() { + if (!mSurfaceControl.get()) { + mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"), + gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888); - SurfaceComposerClient::openGlobalTransaction(); - control->setLayer(0x7FFFFFF); - control->show(); - SurfaceComposerClient::closeGlobalTransaction(); + SurfaceComposerClient::openGlobalTransaction(); + mSurfaceControl->setLayer(0x7FFFFFF); + mSurfaceControl->show(); + SurfaceComposerClient::closeGlobalTransaction(); + } - return control; + return mSurfaceControl->getSurface(); } + +void TestContext::waitForVsync() { + // Request vsync + mDisplayEventReceiver.requestNextVsync(); + + // Wait + mLooper->pollOnce(-1); + + // Drain it + DisplayEventReceiver::Event buf[100]; + while (mDisplayEventReceiver.getEvents(buf, 100) > 0) { } +} + +} // namespace test +} // namespace uirenderer +} // namespace android + diff --git a/libs/hwui/tests/TestContext.h b/libs/hwui/tests/TestContext.h index 8a5d530..7b30fc1 100644 --- a/libs/hwui/tests/TestContext.h +++ b/libs/hwui/tests/TestContext.h @@ -17,17 +17,39 @@ #ifndef TESTCONTEXT_H #define TESTCONTEXT_H -#include <ui/DisplayInfo.h> +#include <gui/DisplayEventReceiver.h> +#include <gui/ISurfaceComposer.h> +#include <gui/SurfaceComposerClient.h> #include <gui/SurfaceControl.h> +#include <gui/Surface.h> +#include <ui/DisplayInfo.h> +#include <utils/Looper.h> + +namespace android { +namespace uirenderer { +namespace test { + +extern DisplayInfo gDisplay; +#define dp(x) ((x) * android::uirenderer::test::gDisplay.density) + +class TestContext { +public: + TestContext(); + ~TestContext(); + + sp<Surface> surface(); -extern android::DisplayInfo gDisplay; -#define dp(x) ((x) * gDisplay.density) + void waitForVsync(); -// Initializes all the static globals that are shared across all contexts -// such as display info -void createTestEnvironment(); +private: + sp<SurfaceComposerClient> mSurfaceComposerClient; + sp<SurfaceControl> mSurfaceControl; + DisplayEventReceiver mDisplayEventReceiver; + sp<Looper> mLooper; +}; -// Defaults to fullscreen -android::sp<android::SurfaceControl> createWindow(int width = -1, int height = -1); +} // namespace test +} // namespace uirenderer +} // namespace android #endif diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index d847d13..a12dac7 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -24,16 +24,18 @@ #include <DisplayListRenderer.h> #include <RenderNode.h> #include <renderthread/RenderProxy.h> +#include <renderthread/RenderTask.h> #include "TestContext.h" using namespace android; using namespace android::uirenderer; using namespace android::uirenderer::renderthread; +using namespace android::uirenderer::test; class ContextFactory : public IContextFactory { public: - virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { + virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override { return new AnimationContext(clock); } }; @@ -41,7 +43,7 @@ public: static DisplayListRenderer* startRecording(RenderNode* node) { DisplayListRenderer* renderer = new DisplayListRenderer(); renderer->setViewport(node->getWidth(), node->getHeight()); - renderer->prepare(false); + renderer->prepare(); return renderer; } @@ -66,24 +68,23 @@ sp<RenderNode> createCard(int x, int y, int width, int height) { return node; } -int main() { - createTestEnvironment(); +int main(int argc, char* argv[]) { + TestContext testContext; // create the native surface const int width = gDisplay.w; const int height = gDisplay.h; - sp<SurfaceControl> control = createWindow(width, height); - sp<Surface> surface = control->getSurface(); + sp<Surface> surface = testContext.surface(); RenderNode* rootNode = new RenderNode(); - rootNode->incStrong(0); + rootNode->incStrong(nullptr); rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height); rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); rootNode->mutateStagingProperties().setClipToBounds(false); 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; @@ -110,6 +111,8 @@ int main() { endRecording(renderer, rootNode); for (int i = 0; i < 150; i++) { + testContext.waitForVsync(); + ATRACE_NAME("UI-Draw Frame"); for (size_t ci = 0; ci < cards.size(); ci++) { cards[ci]->mutateStagingProperties().setTranslationX(i); @@ -118,13 +121,11 @@ int main() { } nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density); - usleep(12000); } sleep(5); - delete proxy; - rootNode->decStrong(0); + rootNode->decStrong(nullptr); printf("Success!\n"); return 0; diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index 5a933ab..10e8b9e 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 d1269f0..eb4ab64 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/PaintUtils.h b/libs/hwui/utils/PaintUtils.h new file mode 100644 index 0000000..fa0ae03 --- /dev/null +++ b/libs/hwui/utils/PaintUtils.h @@ -0,0 +1,64 @@ +/* + * 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 PAINT_UTILS_H +#define PAINT_UTILS_H + +namespace android { +namespace uirenderer { + +class PaintUtils { +public: + + /** + * Safely retrieves the mode from the specified xfermode. If the specified + * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode. + */ + static inline SkXfermode::Mode getXfermode(SkXfermode* mode) { + SkXfermode::Mode resultMode; + if (!SkXfermode::AsMode(mode, &resultMode)) { + resultMode = SkXfermode::kSrcOver_Mode; + } + return resultMode; + } + + // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? + static inline bool paintWillNotDraw(const SkPaint& paint) { + return paint.getAlpha() == 0 + && !paint.getColorFilter() + && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; + } + + // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? + static inline bool paintWillNotDrawText(const SkPaint& paint) { + return paint.getAlpha() == 0 + && paint.getLooper() == nullptr + && !paint.getColorFilter() + && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; + } + + static bool isBlendedColorFilter(const SkColorFilter* filter) { + if (filter == nullptr) { + return false; + } + return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; + } + +}; // class PaintUtils + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* PAINT_UTILS_H */ diff --git a/libs/hwui/utils/SortedList.h b/libs/hwui/utils/SortedList.h index 2fa890a..a2c8c52 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 dc385b5..b101826 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) diff --git a/libs/hwui/utils/Timing.h b/libs/hwui/utils/Timing.h index eced987..dd8847a 100644 --- a/libs/hwui/utils/Timing.h +++ b/libs/hwui/utils/Timing.h @@ -24,12 +24,12 @@ class MethodTimer { public: MethodTimer(const char* name) : mMethodName(name) { - gettimeofday(&mStart, NULL); + gettimeofday(&mStart, nullptr); } ~MethodTimer() { struct timeval stop; - gettimeofday(&stop, NULL); + gettimeofday(&stop, nullptr); long long elapsed = (stop.tv_sec * 1000000) - (mStart.tv_sec * 1000000) + (stop.tv_usec - mStart.tv_usec); ALOGD("%s took %.2fms", mMethodName, elapsed / 1000.0); |