diff options
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 16 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 7 | ||||
-rw-r--r-- | libs/hwui/GlLayer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/GlLayer.h | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 40 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 28 | ||||
-rw-r--r-- | libs/hwui/VkLayer.h | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaPipeline.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/utils/Color.cpp | 54 | ||||
-rw-r--r-- | libs/hwui/utils/Color.h | 3 |
15 files changed, 144 insertions, 31 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index be7d663b412f..569de76f294e 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -40,7 +40,6 @@ DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayer } DeferredLayerUpdater::~DeferredLayerUpdater() { - SkSafeUnref(mColorFilter); setTransform(nullptr); mRenderState.unregisterDeferredLayerUpdater(this); destroyLayer(); @@ -67,8 +66,11 @@ void DeferredLayerUpdater::destroyLayer() { void DeferredLayerUpdater::setPaint(const SkPaint* paint) { mAlpha = PaintUtils::getAlphaDirect(paint); mMode = PaintUtils::getBlendModeDirect(paint); - SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr; - SkRefCnt_SafeAssign(mColorFilter, colorFilter); + if (paint) { + mColorFilter = paint->refColorFilter(); + } else { + mColorFilter.reset(); + } } void DeferredLayerUpdater::apply() { @@ -143,7 +145,7 @@ void DeferredLayerUpdater::doUpdateTexImage() { #endif mSurfaceTexture->getTransformMatrix(transform); - updateLayer(forceFilter, transform); + updateLayer(forceFilter, transform, mSurfaceTexture->getCurrentDataSpace()); } } @@ -153,17 +155,19 @@ void DeferredLayerUpdater::doUpdateVkTexImage() { Layer::Api::OpenGL, Layer::Api::Vulkan); static const mat4 identityMatrix; - updateLayer(false, identityMatrix.data); + updateLayer(false, identityMatrix.data, HAL_DATASPACE_UNKNOWN); VkLayer* vkLayer = static_cast<VkLayer*>(mLayer); vkLayer->updateTexture(); } -void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform) { +void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform, + android_dataspace dataspace) { mLayer->setBlend(mBlend); mLayer->setForceFilter(forceFilter); mLayer->setSize(mWidth, mHeight); mLayer->getTexTransform().load(textureTransform); + mLayer->setDataSpace(dataspace); } void DeferredLayerUpdater::detachSurfaceTexture() { diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 9dc029fd3852..fe3ee7a2b4c6 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -20,6 +20,7 @@ #include <SkMatrix.h> #include <cutils/compiler.h> #include <gui/GLConsumer.h> +#include <system/graphics.h> #include <utils/StrongPointer.h> #include <GLES2/gl2.h> @@ -41,7 +42,7 @@ public: // Note that DeferredLayerUpdater assumes it is taking ownership of the layer // and will not call incrementRef on it as a result. typedef std::function<Layer*(RenderState& renderState, uint32_t layerWidth, - uint32_t layerHeight, SkColorFilter* colorFilter, int alpha, + uint32_t layerHeight, sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend)> CreateLayerFn; ANDROID_API explicit DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn, @@ -96,7 +97,7 @@ public: void detachSurfaceTexture(); - void updateLayer(bool forceFilter, const float* textureTransform); + void updateLayer(bool forceFilter, const float* textureTransform, android_dataspace dataspace); void destroyLayer(); @@ -109,7 +110,7 @@ private: int mWidth = 0; int mHeight = 0; bool mBlend = false; - SkColorFilter* mColorFilter = nullptr; + sk_sp<SkColorFilter> mColorFilter; int mAlpha = 255; SkBlendMode mMode = SkBlendMode::kSrcOver; sp<GLConsumer> mSurfaceTexture; diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp index 32a30149e476..42ae29d76898 100644 --- a/libs/hwui/GlLayer.cpp +++ b/libs/hwui/GlLayer.cpp @@ -32,7 +32,7 @@ namespace android { namespace uirenderer { GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight, - SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) + sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend) : Layer(renderState, Api::OpenGL, colorFilter, alpha, mode) , caches(Caches::getInstance()) , texture(caches) { diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h index 1b091914f318..28749a0d125c 100644 --- a/libs/hwui/GlLayer.h +++ b/libs/hwui/GlLayer.h @@ -32,7 +32,7 @@ class Caches; class GlLayer : public Layer { public: GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight, - SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend); + sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend); virtual ~GlLayer(); uint32_t getWidth() const override { return texture.mWidth; } diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 86950d5ebb10..fb8f0337c95e 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -18,34 +18,58 @@ #include "renderstate/RenderState.h" -#include <SkColorFilter.h> +#include <SkToSRGBColorFilter.h> namespace android { namespace uirenderer { -Layer::Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha, +Layer::Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode) : GpuMemoryTracker(GpuObjectType::Layer) , mRenderState(renderState) , mApi(api) - , colorFilter(nullptr) + , mColorFilter(colorFilter) , alpha(alpha) , mode(mode) { // 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(nullptr); - + buildColorSpaceWithFilter(); renderState.registerLayer(this); } Layer::~Layer() { - SkSafeUnref(colorFilter); - mRenderState.unregisterLayer(this); } -void Layer::setColorFilter(SkColorFilter* filter) { - SkRefCnt_SafeAssign(colorFilter, filter); +void Layer::setColorFilter(sk_sp<SkColorFilter> filter) { + if (filter != mColorFilter) { + mColorFilter = filter; + buildColorSpaceWithFilter(); + } +} + +void Layer::setDataSpace(android_dataspace dataspace) { + if (dataspace != mCurrentDataspace) { + mCurrentDataspace = dataspace; + buildColorSpaceWithFilter(); + } +} + +void Layer::buildColorSpaceWithFilter() { + sk_sp<SkColorFilter> colorSpaceFilter; + sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace(mCurrentDataspace); + if (colorSpace && !colorSpace->isSRGB()) { + colorSpaceFilter = SkToSRGBColorFilter::Make(colorSpace); + } + + if (mColorFilter && colorSpaceFilter) { + mColorSpaceWithFilter = mColorFilter->makeComposed(colorSpaceFilter); + } else if (colorSpaceFilter) { + mColorSpaceWithFilter = colorSpaceFilter; + } else { + mColorSpaceWithFilter = mColorFilter; + } } void Layer::postDecStrong() { diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 69213817f8af..89bcddcc96d0 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -19,6 +19,8 @@ #include <GpuMemoryTracker.h> #include <utils/RefBase.h> +#include <SkColorFilter.h> +#include <SkColorSpace.h> #include <SkBlendMode.h> #include <SkPaint.h> @@ -72,9 +74,15 @@ public: inline SkBlendMode getMode() const { return mode; } - inline SkColorFilter* getColorFilter() const { return colorFilter; } + inline SkColorFilter* getColorFilter() const { return mColorFilter.get(); } - void setColorFilter(SkColorFilter* filter); + void setColorFilter(sk_sp<SkColorFilter> filter); + + void setDataSpace(android_dataspace dataspace); + + void setColorSpace(sk_sp<SkColorSpace> colorSpace); + + inline sk_sp<SkColorFilter> getColorSpaceWithFilter() const { return mColorSpaceWithFilter; } inline mat4& getTexTransform() { return texTransform; } @@ -87,18 +95,30 @@ public: void postDecStrong(); protected: - Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha, + Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter>, int alpha, SkBlendMode mode); RenderState& mRenderState; private: + void buildColorSpaceWithFilter(); + Api mApi; /** * Color filter used to draw this layer. Optional. */ - SkColorFilter* colorFilter; + sk_sp<SkColorFilter> mColorFilter; + + /** + * Colorspace of the contents of the layer. Optional. + */ + android_dataspace mCurrentDataspace = HAL_DATASPACE_UNKNOWN; + + /** + * A color filter that is the combination of the mColorFilter and mColorSpace. Optional. + */ + sk_sp<SkColorFilter> mColorSpaceWithFilter; /** * Indicates raster data backing the layer is scaled, requiring filtration. diff --git a/libs/hwui/VkLayer.h b/libs/hwui/VkLayer.h index f23f4726017e..e9664d04b7a5 100644 --- a/libs/hwui/VkLayer.h +++ b/libs/hwui/VkLayer.h @@ -28,7 +28,7 @@ namespace uirenderer { class VkLayer : public Layer { public: VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight, - SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) + sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend) : Layer(renderState, Api::Vulkan, colorFilter, alpha, mode) , mWidth(layerWidth) , mHeight(layerHeight) diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index 896c01ce910c..00ba71302dc2 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -50,9 +50,13 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer GlLayer* glLayer = static_cast<GlLayer*>(layer); GrGLTextureInfo externalTexture; externalTexture.fTarget = glLayer->getRenderTarget(); - SkASSERT(GL_RGBA == glLayer->getTexture().internalFormat()); - externalTexture.fFormat = GL_RGBA8; externalTexture.fID = glLayer->getTextureId(); + // The format may not be GL_RGBA8, but given the DeferredLayerUpdater and GLConsumer don't + // expose that info we use it as our default. Further, given that we only use this texture + // as a source this will not impact how Skia uses the texture. The only potential affect + // this is anticipated to have is that for some format types if we are not bound as an OES + // texture we may get invalid results for SKP capture if we read back the texture. + externalTexture.fFormat = GL_RGBA8; GrBackendTexture backendTexture(layerWidth, layerHeight, GrMipMapped::kNo, externalTexture); layerImage = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr); @@ -83,7 +87,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer SkPaint paint; paint.setAlpha(layer->getAlpha()); paint.setBlendMode(layer->getMode()); - paint.setColorFilter(sk_ref_sp(layer->getColorFilter())); + paint.setColorFilter(layer->getColorSpaceWithFilter()); const bool nonIdentityMatrix = !matrix.isIdentity(); if (nonIdentityMatrix) { diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index b7aa78b7afae..7dd441b5199c 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -158,7 +158,7 @@ bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBi } static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight, - SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) { + sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend) { GlLayer* layer = new GlLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend); layer->generateTexture(); diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 9e7304678021..d66cba12ad99 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -147,6 +147,7 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, GrContext* currentContext = layerNode->getLayerSurface()->getCanvas()->getGrContext(); if (cachedContext.get() != currentContext) { if (cachedContext.get()) { + ATRACE_NAME("flush layers (context changed)"); cachedContext->flush(); } cachedContext.reset(SkSafeRef(currentContext)); @@ -155,6 +156,7 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, } if (cachedContext.get()) { + ATRACE_NAME("flush layers"); cachedContext->flush(); } } diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 653007482c0a..5825060f902a 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -115,7 +115,8 @@ bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bi } static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight, - SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) { + sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, + bool blend) { return new VkLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend); } diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 16c5afdc3dcf..1555c0a06ec4 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -72,7 +72,7 @@ sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater( layerUpdater->setTransform(&transform); // updateLayer so it's ready to draw - layerUpdater->updateLayer(true, Matrix4::identity().data); + layerUpdater->updateLayer(true, Matrix4::identity().data, HAL_DATASPACE_UNKNOWN); if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) { static_cast<GlLayer*>(layerUpdater->backingLayer()) ->setRenderTarget(GL_TEXTURE_EXTERNAL_OES); diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp index b8b5050faa11..f29830f0e34b 100644 --- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp +++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp @@ -44,7 +44,7 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { // push the deferred updates to the layer Matrix4 scaledMatrix; scaledMatrix.loadScale(0.5, 0.5, 0.0); - layerUpdater->updateLayer(true, scaledMatrix.data); + layerUpdater->updateLayer(true, scaledMatrix.data, HAL_DATASPACE_UNKNOWN); if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) { GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer()); glLayer->setRenderTarget(GL_TEXTURE_EXTERNAL_OES); diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp index c2af867657bf..75740e8b5baf 100644 --- a/libs/hwui/utils/Color.cpp +++ b/libs/hwui/utils/Color.cpp @@ -16,6 +16,8 @@ #include "Color.h" + +#include <utils/Log.h> #include <cmath> namespace android { @@ -53,5 +55,57 @@ bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace) { return false; } +sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { + + SkColorSpace::Gamut gamut; + switch (dataspace & HAL_DATASPACE_STANDARD_MASK) { + case HAL_DATASPACE_STANDARD_BT709: + gamut = SkColorSpace::kSRGB_Gamut; + break; + case HAL_DATASPACE_STANDARD_BT2020: + gamut = SkColorSpace::kRec2020_Gamut; + break; + case HAL_DATASPACE_STANDARD_DCI_P3: + gamut = SkColorSpace::kDCIP3_D65_Gamut; + break; + case HAL_DATASPACE_STANDARD_ADOBE_RGB: + gamut = SkColorSpace::kAdobeRGB_Gamut; + break; + case HAL_DATASPACE_STANDARD_UNSPECIFIED: + return nullptr; + case HAL_DATASPACE_STANDARD_BT601_625: + case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED: + case HAL_DATASPACE_STANDARD_BT601_525: + case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED: + case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE: + case HAL_DATASPACE_STANDARD_BT470M: + case HAL_DATASPACE_STANDARD_FILM: + default: + ALOGW("Unsupported Gamut: %d", dataspace); + return nullptr; + } + + switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { + case HAL_DATASPACE_TRANSFER_LINEAR: + return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, gamut); + case HAL_DATASPACE_TRANSFER_SRGB: + return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, gamut); + case HAL_DATASPACE_TRANSFER_GAMMA2_2: + return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); + case HAL_DATASPACE_TRANSFER_GAMMA2_6: + return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); + case HAL_DATASPACE_TRANSFER_GAMMA2_8: + return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); + case HAL_DATASPACE_TRANSFER_UNSPECIFIED: + return nullptr; + case HAL_DATASPACE_TRANSFER_SMPTE_170M: + case HAL_DATASPACE_TRANSFER_ST2084: + case HAL_DATASPACE_TRANSFER_HLG: + default: + ALOGW("Unsupported Gamma: %d", dataspace); + return nullptr; + } +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h index 7ac0d963732f..2bec1f5f7852 100644 --- a/libs/hwui/utils/Color.h +++ b/libs/hwui/utils/Color.h @@ -17,6 +17,7 @@ #define COLOR_H #include <math.h> +#include <system/graphics.h> #include <SkColor.h> #include <SkColorSpace.h> @@ -111,6 +112,8 @@ static constexpr float EOCF(float srgb) { // approximated with the native sRGB transfer function. This method // returns true for sRGB, gamma 2.2 and Display P3 for instance bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace); + +sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace); } /* namespace uirenderer */ } /* namespace android */ |