diff options
| author | 2018-10-26 14:25:30 -0700 | |
|---|---|---|
| committer | 2018-10-30 16:54:34 -0700 | |
| commit | 2a6ab2aa52b9657b6c7b4401b3ec225c3a65b5c3 (patch) | |
| tree | c1ed6b430bf0987155b0f17f2c1e55dad3051e0f | |
| parent | 27631c9c42e8cfbfd7b42d60818b7954dcfbbc1e (diff) | |
SurfaceFlinger: fix color transfer test
Add support for color management in
LayerTransactionTest.SetColorTransformBasic.
If color management is enabled, some considerations are needed
for the expected color output.
Test: adb shell /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test
Change-Id: I7be7d561e7683fd57db0519932c4c308a6350c0d
| -rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 21 | ||||
| -rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 3 | ||||
| -rw-r--r-- | libs/gui/tests/Surface_test.cpp | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/Transaction_test.cpp | 74 |
6 files changed, 101 insertions, 5 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index cf9d4c5aba..cc0a307c65 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -583,6 +583,21 @@ public: } return error; } + + virtual bool isColorManagementUsed() const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + remote()->transact(BnSurfaceComposer::IS_COLOR_MANAGEMET_USED, data, &reply); + int32_t result = 0; + status_t err = reply.readInt32(&result); + if (err != NO_ERROR) { + ALOGE("ISurfaceComposer::isColorManagementUsed: error " + "retrieving result: %s (%d)", + strerror(-err), -err); + return false; + } + return result != 0; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -920,6 +935,12 @@ status_t BnSurfaceComposer::onTransact( } return NO_ERROR; } + case IS_COLOR_MANAGEMET_USED: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + int32_t result = isColorManagementUsed() ? 1 : 0; + reply->writeInt32(result); + return NO_ERROR; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 781e06275d..35cb3be7df 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -282,6 +282,8 @@ public: virtual status_t getCompositionPreference(ui::Dataspace* dataSpace, ui::PixelFormat* pixelFormat) const = 0; + + virtual bool isColorManagementUsed() const = 0; }; // ---------------------------------------------------------------------------- @@ -320,6 +322,7 @@ public: GET_LAYER_DEBUG_INFO, CREATE_SCOPED_CONNECTION, GET_COMPOSITION_PREFERENCE, + IS_COLOR_MANAGEMET_USED, }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 500df055c2..25f762bbe3 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -633,6 +633,8 @@ public: return NO_ERROR; } + virtual bool isColorManagementUsed() const { return false; } + protected: IBinder* onAsBinder() override { return nullptr; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ab07bc6815..fc8ca54797 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -513,6 +513,10 @@ sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { return mDisplayTokens[id]; } +bool SurfaceFlinger::isColorManagementUsed() const { + return useColorManagement; +} + void SurfaceFlinger::bootFinished() { if (mStartPropertySetThread->join() != NO_ERROR) { @@ -4744,6 +4748,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case SET_TRANSACTION_STATE: // Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h case CREATE_SCOPED_CONNECTION: + case IS_COLOR_MANAGEMET_USED: case GET_COMPOSITION_PREFERENCE: { return OK; } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 9e47b3fd9f..73c9d952d9 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -462,6 +462,7 @@ private: virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const; status_t getCompositionPreference(ui::Dataspace* outDataSpace, ui::PixelFormat* outPixelFormat) const override; + virtual bool isColorManagementUsed() const; /* ------------------------------------------------------------------------ * DeathRecipient interface diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 3166a8c752..c814142f49 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -30,6 +30,7 @@ #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> +#include <ui/ColorSpace.h> #include <ui/DisplayInfo.h> #include <ui/Rect.h> #include <utils/String8.h> @@ -314,6 +315,10 @@ protected: ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient"; ASSERT_NO_FATAL_FAILURE(SetUpDisplay()); + + sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + sp<IBinder> binder = sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + mColorManagementUsed = sf->isColorManagementUsed(); } virtual void TearDown() { @@ -470,6 +475,8 @@ protected: void setMatrixWithResizeHelper(uint32_t layerType); sp<SurfaceControl> mBlackBgSurface; + bool mColorManagementUsed; + private: void SetUpDisplay() { mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); @@ -2064,6 +2071,47 @@ TEST_F(LayerTransactionTest, SetSidebandStreamNull_BufferState) { Transaction().setSidebandStream(layer, nullptr).apply(); } +class ColorTransformHelper { +public: + static void DegammaColorSingle(half& s) { + if (s <= 0.03928f) + s = s / 12.92f; + else + s = pow((s + 0.055f) / 1.055f, 2.4f); + } + + static void DegammaColor(half3& color) { + DegammaColorSingle(color.r); + DegammaColorSingle(color.g); + DegammaColorSingle(color.b); + } + + static void GammaColorSingle(half& s) { + if (s <= 0.0031308f) { + s = s * 12.92f; + } else { + s = 1.055f * pow(s, (1.0f / 2.4f)) - 0.055f; + } + } + + static void GammaColor(half3& color) { + GammaColorSingle(color.r); + GammaColorSingle(color.g); + GammaColorSingle(color.b); + } + + static void applyMatrix(half3& color, const mat3& mat) { + half3 ret = half3(0); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + ret[i] = ret[i] + color[j] * mat[j][i]; + } + } + color = ret; + } +}; + TEST_F(LayerTransactionTest, SetColorTransformBasic) { sp<SurfaceControl> colorLayer; ASSERT_NO_FATAL_FAILURE( @@ -2076,19 +2124,35 @@ TEST_F(LayerTransactionTest, SetColorTransformBasic) { } const half3 color(50.0f / 255.0f, 100.0f / 255.0f, 150.0f / 255.0f); - const Color expected = {90, 90, 90, 255}; - // this is handwavy, but the precison loss scaled by 255 (8-bit per - // channel) should be less than one - const uint8_t tolerance = 1; + half3 expected = color; mat3 matrix; matrix[0][0] = 0.3; matrix[1][0] = 0.59; matrix[2][0] = 0.11; matrix[0][1] = 0.3; matrix[1][1] = 0.59; matrix[2][1] = 0.11; matrix[0][2] = 0.3; matrix[1][2] = 0.59; matrix[2][2] = 0.11; + + // degamma before applying the matrix + if (mColorManagementUsed) { + ColorTransformHelper::DegammaColor(expected); + } + + ColorTransformHelper::applyMatrix(expected, matrix); + + if (mColorManagementUsed) { + ColorTransformHelper::GammaColor(expected); + } + + const Color expectedColor = {uint8_t(expected.r * 255), uint8_t(expected.g * 255), + uint8_t(expected.b * 255), 255}; + + // this is handwavy, but the precison loss scaled by 255 (8-bit per + // channel) should be less than one + const uint8_t tolerance = 1; + Transaction().setColor(colorLayer, color) .setColorTransform(colorLayer, matrix, vec3()).apply(); { SCOPED_TRACE("new color"); - screenshot()->expectColor(Rect(0, 0, 32, 32), expected, tolerance); + screenshot()->expectColor(Rect(0, 0, 32, 32), expectedColor, tolerance); } } |