diff options
5 files changed, 50 insertions, 81 deletions
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 9ecf8ce2e7..ea7dc2f1fd 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -210,42 +210,16 @@ void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha, bool opaque } } -void GLES20RenderEngine::setColorMode(android_color_mode mode) { - ALOGV("setColorMode: %s (0x%x)", decodeColorMode(mode).c_str(), mode); - - if (mColorMode == mode) return; - - if (!mPlatformHasWideColor || !mDisplayHasWideColor || mode == HAL_COLOR_MODE_SRGB || - mode == HAL_COLOR_MODE_NATIVE) { - // We are returning back to our default color_mode - mUseWideColor = false; - mWideColorFrameCount = 0; - } else { - mUseWideColor = true; - } - - mColorMode = mode; -} - -void GLES20RenderEngine::setSourceDataSpace(android_dataspace source) { - if (source == HAL_DATASPACE_UNKNOWN) { - // Treat UNKNOWN as SRGB - source = HAL_DATASPACE_V0_SRGB; - } - mDataSpace = source; -} - void GLES20RenderEngine::setSourceY410BT2020(bool enable) { mState.setY410BT2020(enable); } -void GLES20RenderEngine::setWideColor(bool hasWideColor) { - ALOGV("setWideColor: %s", hasWideColor ? "true" : "false"); - mDisplayHasWideColor = hasWideColor; +void GLES20RenderEngine::setSourceDataSpace(android_dataspace source) { + mDataSpace = source; } -bool GLES20RenderEngine::usesWideColor() { - return mUseWideColor; +void GLES20RenderEngine::setOutputDataSpace(android_dataspace dataspace) { + mOutputDataSpace = dataspace; } void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) { @@ -326,17 +300,13 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { glVertexAttribPointer(Program::position, mesh.getVertexSize(), GL_FLOAT, GL_FALSE, mesh.getByteStride(), mesh.getPositions()); - if (usesWideColor()) { + // DISPLAY_P3 is the only supported wide color output + if (mPlatformHasWideColor && mOutputDataSpace == HAL_DATASPACE_DISPLAY_P3) { Description wideColorState = mState; switch (int(mDataSpace)) { case HAL_DATASPACE_DISPLAY_P3: // input matches output break; - case HAL_DATASPACE_V0_SCRGB_LINEAR: - wideColorState.setColorMatrix(mState.getColorMatrix() * mSrgbToDisplayP3); - wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR); - wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB); - break; case HAL_DATASPACE_BT2020_PQ: case HAL_DATASPACE_BT2020_ITU_PQ: wideColorState.setColorMatrix(mState.getColorMatrix() * mBt2020ToDisplayP3); @@ -345,8 +315,13 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { wideColorState.enableToneMapping(true); break; default: + // treat all other dataspaces as sRGB wideColorState.setColorMatrix(mState.getColorMatrix() * mSrgbToDisplayP3); - wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB); + if ((mDataSpace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_LINEAR) { + wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR); + } else { + wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB); + } wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB); ALOGV("drawMesh: gamut transform applied"); break; @@ -356,8 +331,9 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); if (outputDebugPPMs) { + static uint64_t wideColorFrameCount = 0; std::ostringstream out; - out << "/data/texture_out" << mWideColorFrameCount++; + out << "/data/texture_out" << wideColorFrameCount++; writePPM(out.str().c_str(), mVpWidth, mVpHeight); } } else { @@ -373,11 +349,9 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { void GLES20RenderEngine::dump(String8& result) { RenderEngine::dump(result); - if (usesWideColor()) { - result.append("Wide-color: On\n"); - } else { - result.append("Wide-color: Off\n"); - } + result.appendFormat("RenderEngine last dataspace conversion: (%s) to (%s)\n", + dataspaceDetails(mDataSpace).c_str(), + dataspaceDetails(mOutputDataSpace).c_str()); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index 6e86ea2680..db3f79281e 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -72,27 +72,20 @@ protected: const half4& color) override; // Color management related functions and state - void setColorMode(android_color_mode mode); - void setSourceDataSpace(android_dataspace source); - void setSourceY410BT2020(bool enable); - void setWideColor(bool hasWideColor); - bool usesWideColor(); - - // Current color mode of display using the render engine - android_color_mode mColorMode = HAL_COLOR_MODE_NATIVE; + void setSourceY410BT2020(bool enable) override; + void setSourceDataSpace(android_dataspace source) override; + void setOutputDataSpace(android_dataspace dataspace) override; // Current dataspace of layer being rendered - android_dataspace mDataSpace = HAL_DATASPACE_V0_SRGB; + android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN; - // Indicate if wide-color mode is needed or not - bool mDisplayHasWideColor = false; - bool mUseWideColor = false; - uint64_t mWideColorFrameCount = 0; + // Current output dataspace of the render engine + android_dataspace mOutputDataSpace = HAL_DATASPACE_UNKNOWN; // Currently only supporting sRGB, BT2020 and DisplayP3 color spaces + const bool mPlatformHasWideColor = false; mat4 mSrgbToDisplayP3; mat4 mBt2020ToDisplayP3; - bool mPlatformHasWideColor = false; virtual void setupLayerTexturing(const Texture& texture); virtual void setupLayerBlackedOut(); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index eacef384b7..d1405740e6 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -108,11 +108,6 @@ public: bool yswap, Transform::orientation_flags rotation) = 0; virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture, const half4& color) = 0; - virtual void setColorMode(android_color_mode mode) = 0; - virtual void setSourceDataSpace(android_dataspace source) = 0; - virtual void setSourceY410BT2020(bool enable) = 0; - virtual void setWideColor(bool hasWideColor) = 0; - virtual bool usesWideColor() = 0; virtual void setupLayerTexturing(const Texture& texture) = 0; virtual void setupLayerBlackedOut() = 0; virtual void setupFillWithColor(float r, float g, float b, float a) = 0; @@ -122,6 +117,11 @@ public: virtual void disableTexturing() = 0; virtual void disableBlending() = 0; + // wide color support + virtual void setSourceY410BT2020(bool enable) = 0; + virtual void setSourceDataSpace(android_dataspace source) = 0; + virtual void setOutputDataSpace(android_dataspace dataspace) = 0; + // drawing virtual void drawMesh(const Mesh& mesh) = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cae96220c4..cb410a14e1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2266,9 +2266,8 @@ void SurfaceFlinger::processDisplayChangesLocked() { const wp<IBinder>& display(curr.keyAt(i)); if (dispSurface != nullptr) { - bool useWideColorMode = hasWideColorDisplay; - if (!mForceNativeColorMode) { - bool hasWideColorModes = false; + bool hasWideColorSupport = false; + if (hasWideColorDisplay) { std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(state.type); for (android_color_mode_t colorMode : modes) { @@ -2276,13 +2275,12 @@ void SurfaceFlinger::processDisplayChangesLocked() { case HAL_COLOR_MODE_DISPLAY_P3: case HAL_COLOR_MODE_ADOBE_RGB: case HAL_COLOR_MODE_DCI_P3: - hasWideColorModes = true; + hasWideColorSupport = true; break; default: break; } } - useWideColorMode = hasWideColorModes && hasWideColorDisplay; } bool hasHdrSupport = false; @@ -2296,11 +2294,11 @@ void SurfaceFlinger::processDisplayChangesLocked() { sp<DisplayDevice> hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, - dispSurface, producer, useWideColorMode, + dispSurface, producer, hasWideColorSupport, hasHdrSupport); android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE; - if (useWideColorMode) { + if (hasWideColorSupport) { defaultColorMode = HAL_COLOR_MODE_SRGB; } setActiveColorModeInternal(hw, defaultColorMode); @@ -2740,10 +2738,13 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev if (hasClientComposition) { ALOGV("hasClientComposition"); - getBE().mRenderEngine->setWideColor( - displayDevice->getWideColorSupport() && !mForceNativeColorMode); - getBE().mRenderEngine->setColorMode(mForceNativeColorMode ? - HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode()); + android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN; + if (displayDevice->getWideColorSupport() && + displayDevice->getActiveColorMode() == HAL_COLOR_MODE_DISPLAY_P3) { + outputDataspace = HAL_DATASPACE_DISPLAY_P3; + } + getBE().mRenderEngine->setOutputDataSpace(outputDataspace); + if (!displayDevice->makeCurrent()) { ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", displayDevice->getDisplayName().string()); @@ -4600,9 +4601,12 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight); } - engine.setWideColor(renderArea.getWideColorSupport() && !mForceNativeColorMode); - engine.setColorMode(mForceNativeColorMode ? HAL_COLOR_MODE_NATIVE - : renderArea.getActiveColorMode()); + android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN; + if (renderArea.getWideColorSupport() && + renderArea.getActiveColorMode() == HAL_COLOR_MODE_DISPLAY_P3) { + outputDataspace = HAL_DATASPACE_DISPLAY_P3; + } + getBE().mRenderEngine->setOutputDataSpace(outputDataspace); // make sure to clear all GL error flags engine.checkErrors(); diff --git a/services/surfaceflinger/tests/unittests/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/MockRenderEngine.h index aefbfcf211..6d3e17ff73 100644 --- a/services/surfaceflinger/tests/unittests/MockRenderEngine.h +++ b/services/surfaceflinger/tests/unittests/MockRenderEngine.h @@ -57,17 +57,15 @@ public: MOCK_METHOD6(setViewportAndProjection, void(size_t, size_t, Rect, size_t, bool, Transform::orientation_flags)); MOCK_METHOD4(setupLayerBlending, void(bool, bool, bool, const half4&)); - MOCK_METHOD1(setColorMode, void(android_color_mode)); - MOCK_METHOD1(setSourceDataSpace, void(android_dataspace)); - MOCK_METHOD1(setSourceY410BT2020, void(bool)); - MOCK_METHOD1(setWideColor, void(bool)); - MOCK_METHOD0(usesWideColor, bool()); MOCK_METHOD1(setupLayerTexturing, void(const Texture&)); MOCK_METHOD0(setupLayerBlackedOut, void()); MOCK_METHOD4(setupFillWithColor, void(float, float, float, float)); MOCK_METHOD1(setupColorTransform, mat4(const mat4&)); MOCK_METHOD0(disableTexturing, void()); MOCK_METHOD0(disableBlending, void()); + MOCK_METHOD1(setSourceY410BT2020, void(bool)); + MOCK_METHOD1(setSourceDataSpace, void(android_dataspace)); + MOCK_METHOD1(setOutputDataSpace, void(android_dataspace)); MOCK_METHOD2(bindNativeBufferAsFrameBuffer, void(ANativeWindowBuffer*, RE::BindNativeBufferAsFramebuffer*)); MOCK_METHOD1(unbindNativeBufferAsFrameBuffer, void(RE::BindNativeBufferAsFramebuffer*)); |