Commit fb5fd43c authored by Khushal's avatar Khushal Committed by Commit Bot

android: Hook up color spaces with SurfaceControl.

Make sure the display buffers are tagged with the correct colorspace and
tag the platform surfaces used with SurfaceControl with this color space.

R=ccameron@chromium.org,piman@chromium.org

Bug: 889328
Change-Id: Iad159f1abe27caa26b3de0701f243cbf970ca581
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1504699
Commit-Queue: Khushal <khushalsagar@chromium.org>
Auto-Submit: Khushal <khushalsagar@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#637970}
parent b02b5e03
......@@ -345,6 +345,7 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
gfx::RectF(device_viewport_size.width(), device_viewport_size.height());
output_surface_plane.resource_size_in_pixels = device_viewport_size;
output_surface_plane.format = output_surface_->GetOverlayBufferFormat();
output_surface_plane.color_space = reshape_device_color_space_;
output_surface_plane.use_output_surface_for_resource = true;
output_surface_plane.overlay_handled = true;
output_surface_plane.is_opaque = true;
......
......@@ -257,6 +257,11 @@ gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) {
return BufferFormat(resource->transferable.format);
}
const gfx::ColorSpace& DisplayResourceProvider::GetColorSpace(ResourceId id) {
ChildResource* resource = GetResource(id);
return resource->transferable.color_space;
}
void DisplayResourceProvider::WaitSyncToken(ResourceId id) {
ChildResource* resource = TryGetResource(id);
// TODO(ericrk): We should never fail TryGetResource, but we appear to
......
......@@ -112,6 +112,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
GLenum GetResourceTextureTarget(ResourceId id);
// Return the format of the underlying buffer that can be used for scanout.
gfx::BufferFormat GetBufferFormat(ResourceId id);
const gfx::ColorSpace& GetColorSpace(ResourceId id);
// Indicates if this resource may be used for a hardware overlay plane.
bool IsOverlayCandidate(ResourceId id);
......
......@@ -227,6 +227,7 @@ bool OverlayCandidate::FromDrawQuadResource(
return false;
candidate->format = resource_provider->GetBufferFormat(resource_id);
candidate->color_space = resource_provider->GetColorSpace(resource_id);
if (!base::ContainsValue(kOverlayFormats, candidate->format))
return false;
......
......@@ -71,6 +71,8 @@ class VIZ_SERVICE_EXPORT OverlayCandidate {
gfx::OverlayTransform transform;
// Format of the buffer to scanout.
gfx::BufferFormat format;
// ColorSpace of the buffer for scanout.
gfx::ColorSpace color_space;
// Size of the resource, in pixels.
gfx::Size resource_size_in_pixels;
// Rect on the display to position the overlay to. Implementer must convert
......
......@@ -306,6 +306,11 @@ std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() {
allocated_count_++;
gl_->BindTexture(texture_target_, texture);
gl_->BindTexImage2DCHROMIUM(texture_target_, id);
// The texture must be bound to the image before setting the color space.
gl_->SetColorSpaceMetadataCHROMIUM(
texture, reinterpret_cast<GLColorSpace>(&color_space_));
return std::make_unique<AllocatedSurface>(this, std::move(buffer), texture,
id, stencil, gfx::Rect(size_));
}
......
......@@ -9,6 +9,7 @@
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gl/android/android_surface_control_compat.h"
namespace viz {
namespace {
......@@ -29,6 +30,14 @@ class OverlayCandidateValidatorImpl : public OverlayCandidateValidator {
// Only update the last candidate that was added to the list. All previous
// overlays should have already been handled.
auto& candidate = surfaces->back();
if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) {
DCHECK(!candidate.use_output_surface_for_resource)
<< "The main overlay must only use color space supported by the "
"device";
candidate.overlay_handled = false;
return;
}
candidate.display_rect =
gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
candidate.overlay_handled = true;
......
......@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "ui/gfx/color_space.h"
extern "C" {
typedef struct ASurfaceTransactionStats ASurfaceTransactionStats;
......@@ -35,6 +36,14 @@ enum {
ASURFACE_TRANSACTION_VISIBILITY_SHOW = 1,
};
enum {
ADATASPACE_UNKNOWN = 0,
ADATASPACE_SCRGB_LINEAR = 406913024,
ADATASPACE_SRGB = 142671872,
ADATASPACE_DISPLAY_P3 = 143261696,
ADATASPACE_BT2020_PQ = 163971072,
};
// ASurfaceTransaction
using pASurfaceTransaction_create = ASurfaceTransaction* (*)(void);
using pASurfaceTransaction_delete = void (*)(ASurfaceTransaction*);
......@@ -66,6 +75,10 @@ using pASurfaceTransaction_setDamageRegion =
ASurfaceControl* surface,
const ARect rects[],
uint32_t count);
using pASurfaceTransaction_setBufferDataSpace =
void (*)(ASurfaceTransaction* transaction,
ASurfaceControl* surface,
uint64_t data_space);
// ASurfaceTransactionStats
using pASurfaceTransactionStats_getPresentFenceFd =
......@@ -121,6 +134,7 @@ struct SurfaceControlMethods {
LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setGeometry);
LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setBufferTransparency);
LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setDamageRegion);
LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setBufferDataSpace);
LOAD_FUNCTION(main_dl_handle, ASurfaceTransactionStats_getPresentFenceFd);
LOAD_FUNCTION(main_dl_handle, ASurfaceTransactionStats_getASurfaceControls);
......@@ -150,6 +164,8 @@ struct SurfaceControlMethods {
pASurfaceTransaction_setBufferTransparency
ASurfaceTransaction_setBufferTransparencyFn;
pASurfaceTransaction_setDamageRegion ASurfaceTransaction_setDamageRegionFn;
pASurfaceTransaction_setBufferDataSpace
ASurfaceTransaction_setBufferDataSpaceFn;
// TransactionStats methods.
pASurfaceTransactionStats_getPresentFenceFd
......@@ -188,6 +204,21 @@ int32_t OverlayTransformToWindowTransform(gfx::OverlayTransform transform) {
return ANATIVEWINDOW_TRANSFORM_IDENTITY;
}
uint64_t ColorSpaceToADataSpace(const gfx::ColorSpace& color_space) {
if (!color_space.IsValid() || color_space == gfx::ColorSpace::CreateSRGB())
return ADATASPACE_SRGB;
if (color_space == gfx::ColorSpace::CreateSCRGBLinear())
return ADATASPACE_SCRGB_LINEAR;
if (color_space == gfx::ColorSpace::CreateDisplayP3D65())
return ADATASPACE_DISPLAY_P3;
// TODO(khushalsagar): Check if we can support BT2020 using
// ADATASPACE_BT2020_PQ.
return ADATASPACE_UNKNOWN;
}
SurfaceControl::TransactionStats ToTransactionStats(
ASurfaceTransactionStats* stats) {
SurfaceControl::TransactionStats transaction_stats;
......@@ -248,6 +279,10 @@ bool SurfaceControl::IsSupported() {
return SurfaceControlMethods::Get().supported;
}
bool SurfaceControl::SupportsColorSpace(const gfx::ColorSpace& color_space) {
return ColorSpaceToADataSpace(color_space) != ADATASPACE_UNKNOWN;
}
SurfaceControl::Surface::Surface() = default;
SurfaceControl::Surface::Surface(const Surface& parent, const char* name) {
......@@ -334,6 +369,13 @@ void SurfaceControl::Transaction::SetDamageRect(const Surface& surface,
transaction_, surface.surface(), &a_rect, 1u);
}
void SurfaceControl::Transaction::SetColorSpace(
const Surface& surface,
const gfx::ColorSpace& color_space) {
SurfaceControlMethods::Get().ASurfaceTransaction_setBufferDataSpaceFn(
transaction_, surface.surface(), ColorSpaceToADataSpace(color_space));
}
void SurfaceControl::Transaction::SetOnCompleteCb(
OnCompleteCb cb,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
......
......@@ -22,12 +22,19 @@ typedef struct ASurfaceControl ASurfaceControl;
typedef struct ASurfaceTransaction ASurfaceTransaction;
}
namespace gfx {
class ColorSpace;
} // namespace gfx
namespace gl {
class GL_EXPORT SurfaceControl {
public:
static bool IsSupported();
// Returns true if overlays with |color_space| are supported by the platform.
static bool SupportsColorSpace(const gfx::ColorSpace& color_space);
class GL_EXPORT Surface : public base::RefCounted<Surface> {
public:
Surface();
......@@ -92,6 +99,8 @@ class GL_EXPORT SurfaceControl {
gfx::OverlayTransform transform);
void SetOpaque(const Surface& surface, bool opaque);
void SetDamageRect(const Surface& surface, const gfx::Rect& rect);
void SetColorSpace(const Surface& surface,
const gfx::ColorSpace& color_space);
// Sets the callback which will be dispatched when the transaction is acked
// by the framework.
......
......@@ -15,6 +15,10 @@ bool GLImage::BindTexImageWithInternalformat(unsigned target,
return false;
}
void GLImage::SetColorSpace(const gfx::ColorSpace& color_space) {
color_space_ = color_space;
}
bool GLImage::EmulatingRGB() const {
return false;
}
......
......@@ -100,7 +100,8 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
std::unique_ptr<gfx::GpuFence> gpu_fence) = 0;
// Set the color space when image is used as an overlay.
virtual void SetColorSpace(const gfx::ColorSpace& color_space) = 0;
virtual void SetColorSpace(const gfx::ColorSpace& color_space);
const gfx::ColorSpace& color_space() const { return color_space_; }
// Flush any preceding rendering for the image.
virtual void Flush() = 0;
......@@ -140,6 +141,8 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
protected:
virtual ~GLImage() {}
gfx::ColorSpace color_space_;
private:
friend class base::RefCounted<GLImage>;
......
......@@ -41,7 +41,6 @@ class GL_EXPORT GLImageAHardwareBuffer : public GLImageEGL {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override {}
void Flush() override;
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......
......@@ -244,10 +244,6 @@ bool GLImageDXGI::ScheduleOverlayPlane(
return false;
}
void GLImageDXGI::SetColorSpace(const gfx::ColorSpace& color_space) {
color_space_ = color_space;
}
bool GLImageDXGI::InitializeHandle(base::win::ScopedHandle handle,
uint32_t level,
gfx::BufferFormat format) {
......
......@@ -48,7 +48,6 @@ class GL_EXPORT GLImageDXGI : public GLImage {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override;
const gfx::ColorSpace& color_space() const { return color_space_; }
Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex() { return keyed_mutex_; }
......@@ -65,7 +64,6 @@ class GL_EXPORT GLImageDXGI : public GLImage {
~GLImageDXGI() override;
gfx::BufferFormat buffer_format_ = gfx::BufferFormat::BGRA_8888;
gfx::ColorSpace color_space_;
base::win::ScopedHandle handle_;
Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex_;
size_t level_ = 0;
......
......@@ -38,7 +38,6 @@ class GL_EXPORT GLImageGLX : public GLImage {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override {}
void Flush() override {}
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......
......@@ -110,10 +110,6 @@ class GL_EXPORT GLImageIOSurface : public GLImage {
base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer_;
gfx::GenericSharedMemoryId io_surface_id_;
// Cache the color space, because re-assigning the same value can be
// expensive.
gfx::ColorSpace color_space_;
base::ThreadChecker thread_checker_;
// The default value of Rec. 601 is based on historical shader code.
gfx::ColorSpace color_space_for_yuv_to_rgb_ = gfx::ColorSpace::CreateREC601();
......
......@@ -453,7 +453,7 @@ GLImage::Type GLImageIOSurface::GetType() const {
void GLImageIOSurface::SetColorSpace(const gfx::ColorSpace& color_space) {
if (color_space_ == color_space)
return;
color_space_ = color_space;
GLImage::SetColorSpace(color_space);
// Prefer to use data from DisplayICCProfiles, which will give a byte-for-byte
// match for color spaces of the system displays. Note that DisplayICCProfiles
......
......@@ -44,7 +44,6 @@ class GL_EXPORT GLImageMemory : public GLImage {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override {}
void Flush() override {}
Type GetType() const override;
......
......@@ -34,7 +34,6 @@ class GL_EXPORT GLImageStub : public GLImage {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override {}
void Flush() override {}
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......
......@@ -40,7 +40,6 @@ class GL_EXPORT GLImageSurfaceTexture : public GLImage {
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
void SetColorSpace(const gfx::ColorSpace& color_space) override {}
void Flush() override {}
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......
......@@ -177,6 +177,11 @@ bool GLSurfaceEGLSurfaceControl::ScheduleOverlayPlane(
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) {
if (!SurfaceControl::SupportsColorSpace(image->color_space())) {
LOG(ERROR) << "Not supported color space used with overlay : "
<< image->color_space().ToString();
}
if (!pending_transaction_)
pending_transaction_.emplace();
......@@ -252,6 +257,12 @@ bool GLSurfaceEGLSurfaceControl::ScheduleOverlayPlane(
pending_transaction_->SetOpaque(*surface_state.surface, opaque);
}
if (uninitialized || surface_state.color_space != image->color_space()) {
surface_state.color_space = image->color_space();
pending_transaction_->SetColorSpace(*surface_state.surface,
image->color_space());
}
return true;
}
......
......@@ -98,6 +98,7 @@ class GL_EXPORT GLSurfaceEGLSurfaceControl : public GLSurfaceEGL {
gfx::Rect src;
gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE;
bool opaque = true;
gfx::ColorSpace color_space;
// Indicates whether buffer for this layer was updated in the currently
// pending transaction, or the last transaction submitted if there isn't
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment