mPresentDisplay(nullptr),
mSetActiveConfig(nullptr),
mSetClientTarget(nullptr),
+ mSetColorTransform(nullptr),
mSetOutputBuffer(nullptr),
mSetPowerMode(nullptr),
mSetVsyncEnabled(nullptr),
mSetLayerBlendMode(nullptr),
mSetLayerColor(nullptr),
mSetLayerCompositionType(nullptr),
+ mSetLayerDataspace(nullptr),
mSetLayerDisplayFrame(nullptr),
mSetLayerPlaneAlpha(nullptr),
mSetLayerSidebandStream(nullptr),
mSetActiveConfig)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
mSetClientTarget)) return;
+ if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
+ mSetColorTransform)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
mSetOutputBuffer)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
mSetLayerColor)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
mSetLayerCompositionType)) return;
+ if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
+ mSetLayerDataspace)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
mSetLayerDisplayFrame)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
return static_cast<Error>(intError);
}
+Error Display::setColorTransform(const android::mat4& matrix,
+ android_color_transform_t hint)
+{
+ int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
+ matrix.asArray(), static_cast<int32_t>(hint));
+ return static_cast<Error>(intError);
+}
+
Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
const sp<Fence>& releaseFence)
{
return static_cast<Error>(intError);
}
+Error Layer::setDataspace(android_dataspace_t dataspace)
+{
+ auto intDataspace = static_cast<int32_t>(dataspace);
+ int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
+ mDisplayId, mId, intDataspace);
+ return static_cast<Error>(intError);
+}
+
Error Layer::setDisplayFrame(const Rect& frame)
{
hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
#undef HWC2_USE_CPP11
#include <ui/HdrCapabilities.h>
+#include <ui/mat4.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
HWC2_PFN_PRESENT_DISPLAY mPresentDisplay;
HWC2_PFN_SET_ACTIVE_CONFIG mSetActiveConfig;
HWC2_PFN_SET_CLIENT_TARGET mSetClientTarget;
+ HWC2_PFN_SET_COLOR_TRANSFORM mSetColorTransform;
HWC2_PFN_SET_OUTPUT_BUFFER mSetOutputBuffer;
HWC2_PFN_SET_POWER_MODE mSetPowerMode;
HWC2_PFN_SET_VSYNC_ENABLED mSetVsyncEnabled;
HWC2_PFN_SET_LAYER_BLEND_MODE mSetLayerBlendMode;
HWC2_PFN_SET_LAYER_COLOR mSetLayerColor;
HWC2_PFN_SET_LAYER_COMPOSITION_TYPE mSetLayerCompositionType;
+ HWC2_PFN_SET_LAYER_DATASPACE mSetLayerDataspace;
HWC2_PFN_SET_LAYER_DISPLAY_FRAME mSetLayerDisplayFrame;
HWC2_PFN_SET_LAYER_PLANE_ALPHA mSetLayerPlaneAlpha;
HWC2_PFN_SET_LAYER_SIDEBAND_STREAM mSetLayerSidebandStream;
buffer_handle_t target,
const android::sp<android::Fence>& acquireFence,
android_dataspace_t dataspace);
+ [[clang::warn_unused_result]] Error setColorTransform(
+ const android::mat4& matrix, android_color_transform_t hint);
[[clang::warn_unused_result]] Error setOutputBuffer(
const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& releaseFence);
[[clang::warn_unused_result]] Error setBlendMode(BlendMode mode);
[[clang::warn_unused_result]] Error setColor(hwc_color_t color);
[[clang::warn_unused_result]] Error setCompositionType(Composition type);
+ [[clang::warn_unused_result]] Error setDataspace(
+ android_dataspace_t dataspace);
[[clang::warn_unused_result]] Error setDisplayFrame(
const android::Rect& frame);
[[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
displayHook<decltype(&Display::setClientTarget),
&Display::setClientTarget, buffer_handle_t, int32_t,
int32_t>);
+ case FunctionDescriptor::SetColorTransform:
+ return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
case FunctionDescriptor::SetOutputBuffer:
return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
displayHook<decltype(&Display::setOutputBuffer),
case FunctionDescriptor::SetLayerCompositionType:
return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
setLayerCompositionTypeHook);
+ case FunctionDescriptor::SetLayerDataspace:
+ return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
case FunctionDescriptor::SetLayerDisplayFrame:
return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
layerHook<decltype(&Layer::setDisplayFrame),
mVsyncEnabled(Vsync::Invalid),
mClientTarget(),
mOutputBuffer(),
+ mHasColorTransform(false),
mLayers(),
mHwc1LayerMap() {}
return Error::None;
}
+Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint)
+{
+ std::unique_lock<std::recursive_mutex> lock(mStateMutex);
+
+ ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
+ static_cast<int32_t>(hint));
+ mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
+ return Error::None;
+}
+
Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
int32_t releaseFence)
{
}
}
+bool HWC2On1Adapter::Display::hasColorTransform() const
+{
+ std::unique_lock<std::recursive_mutex> lock(mStateMutex);
+ return mHasColorTransform;
+}
+
static std::string hwc1CompositionString(int32_t type)
{
switch (type) {
mZ(0),
mReleaseFence(),
mHwc1Id(0),
+ mHasUnsupportedDataspace(false),
mHasUnsupportedPlaneAlpha(false) {}
bool HWC2On1Adapter::SortLayersByZ::operator()(
return Error::None;
}
+Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace)
+{
+ mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN);
+ return Error::None;
+}
+
Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame)
{
mDisplayFrame.setPending(frame);
void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
bool applyAllState)
{
- if (mHasUnsupportedPlaneAlpha) {
+ // HWC1 never supports color transforms or dataspaces and only sometimes
+ // supports plane alpha (depending on the version). These require us to drop
+ // some or all layers to client composition.
+ if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
+ mDisplay.hasColorTransform()) {
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags = HWC_SKIP_LAYER;
return;
HWC2::Error setActiveConfig(hwc2_config_t configId);
HWC2::Error setClientTarget(buffer_handle_t target,
int32_t acquireFence, int32_t dataspace);
+ HWC2::Error setColorTransform(android_color_transform_t hint);
HWC2::Error setOutputBuffer(buffer_handle_t buffer,
int32_t releaseFence);
HWC2::Error setPowerMode(HWC2::PowerMode mode);
void addRetireFence(int fenceFd);
void addReleaseFences(const hwc_display_contents_1& hwcContents);
+ bool hasColorTransform() const;
+
std::string dump() const;
private:
FencedBuffer mClientTarget;
FencedBuffer mOutputBuffer;
+ bool mHasColorTransform;
+
std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers;
std::unordered_map<size_t, std::shared_ptr<Layer>> mHwc1LayerMap;
};
config, attribute, outValue);
}
+ static int32_t setColorTransformHook(hwc2_device_t* device,
+ hwc2_display_t display, const float* /*matrix*/,
+ int32_t /*android_color_transform_t*/ intHint) {
+ // We intentionally throw away the matrix, because if the hint is
+ // anything other than IDENTITY, we have to fall back to client
+ // composition anyway
+ auto hint = static_cast<android_color_transform_t>(intHint);
+ return callDisplayFunction(device, display, &Display::setColorTransform,
+ hint);
+ }
+
static int32_t setPowerModeHook(hwc2_device_t* device,
hwc2_display_t display, int32_t intMode) {
auto mode = static_cast<HWC2::PowerMode>(intMode);
HWC2::Error setBlendMode(HWC2::BlendMode mode);
HWC2::Error setColor(hwc_color_t color);
HWC2::Error setCompositionType(HWC2::Composition type);
+ HWC2::Error setDataspace(android_dataspace_t dataspace);
HWC2::Error setDisplayFrame(hwc_rect_t frame);
HWC2::Error setPlaneAlpha(float alpha);
HWC2::Error setSidebandStream(const native_handle_t* stream);
DeferredFence mReleaseFence;
size_t mHwc1Id;
+ bool mHasUnsupportedDataspace;
bool mHasUnsupportedPlaneAlpha;
};
&Layer::setCompositionType, type);
}
+ static int32_t setLayerDataspaceHook(hwc2_device_t* device,
+ hwc2_display_t display, hwc2_layer_t layer, int32_t intDataspace) {
+ auto dataspace = static_cast<android_dataspace_t>(intDataspace);
+ return callLayerFunction(device, display, layer, &Layer::setDataspace,
+ dataspace);
+ }
+
static int32_t setLayerTransformHook(hwc2_device_t* device,
hwc2_display_t display, hwc2_layer_t layer, int32_t intTransform) {
auto transform = static_cast<HWC2::Transform>(intTransform);