Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Unified Diff: ui/accelerated_widget_mac/ca_renderer_layer_tree.mm

Issue 2391793002: Mac: Fix bugs in Sierra color fix (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/accelerated_widget_mac/ca_renderer_layer_tree.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
index 985b06e9401fbe9c2589a89627b9f8de49d64ee5..a139dc7d073b8da3a68b78e593dce4d946774f1f 100644
--- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
+++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
@@ -10,6 +10,7 @@
#include <GLES2/gl2extchromium.h>
#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/trace_event/trace_event.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -129,10 +130,81 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
} // namespace
+class CARendererLayerTree::SolidColorContents
+ : public base::RefCounted<CARendererLayerTree::SolidColorContents> {
+ public:
+ static scoped_refptr<SolidColorContents> Get(SkColor color);
+ id GetContents() const;
+
+ private:
+ friend class base::RefCounted<SolidColorContents>;
+
+ SolidColorContents(SkColor color, IOSurfaceRef io_surface);
+ ~SolidColorContents();
+
+ SkColor color_ = 0;
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
+ static base::LazyInstance<std::map<SkColor, SolidColorContents*>> map_;
+};
+
+base::LazyInstance<std::map<SkColor, CARendererLayerTree::SolidColorContents*>>
+ CARendererLayerTree::SolidColorContents::map_;
+
+// static
+scoped_refptr<CARendererLayerTree::SolidColorContents>
+CARendererLayerTree::SolidColorContents::Get(SkColor color) {
+ const int kSolidColorContentsSize = 16;
+
+ auto found = map_.Get().find(color);
+ if (found != map_.Get().end())
+ return found->second;
+
+ IOSurfaceRef io_surface = CreateIOSurface(
+ gfx::Size(kSolidColorContentsSize, kSolidColorContentsSize),
+ gfx::BufferFormat::BGRA_8888);
+ if (!io_surface)
+ return nullptr;
+
+ size_t bytes_per_row = IOSurfaceGetBytesPerRowOfPlane(io_surface, 0);
+ IOSurfaceLock(io_surface, 0, NULL);
+ char* row_base_address =
+ reinterpret_cast<char*>(IOSurfaceGetBaseAddress(io_surface));
+ for (int i = 0; i < kSolidColorContentsSize; ++i) {
+ unsigned int* pixel = reinterpret_cast<unsigned int*>(row_base_address);
+ for (int j = 0; j < kSolidColorContentsSize; ++j)
+ *(pixel++) = color;
+ row_base_address += bytes_per_row;
+ }
+ IOSurfaceUnlock(io_surface, 0, NULL);
+
+ return new SolidColorContents(color, io_surface);
+}
+
+id CARendererLayerTree::SolidColorContents::GetContents() const {
+ return static_cast<id>(io_surface_.get());
+}
+
+CARendererLayerTree::SolidColorContents::SolidColorContents(
+ SkColor color,
+ IOSurfaceRef io_surface)
+ : color_(color), io_surface_(io_surface) {
+ DCHECK(map_.Get().find(color_) == map_.Get().end());
+ map_.Get()[color_] = this;
+}
+
+CARendererLayerTree::SolidColorContents::~SolidColorContents() {
+ auto found = map_.Get().find(color_);
+ DCHECK(found != map_.Get().end());
+ DCHECK(found->second == this);
+ map_.Get().erase(color_);
+}
+
CARendererLayerTree::CARendererLayerTree(
- bool allow_av_sample_buffer_display_layer)
+ bool allow_av_sample_buffer_display_layer,
+ bool allow_solid_color_layers)
: allow_av_sample_buffer_display_layer_(
- allow_av_sample_buffer_display_layer) {}
+ allow_av_sample_buffer_display_layer),
+ allow_solid_color_layers_(allow_solid_color_layers) {}
CARendererLayerTree::~CARendererLayerTree() {}
bool CARendererLayerTree::ScheduleCALayer(const CARendererLayerParams& params) {
@@ -216,6 +288,9 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
return true;
}
+id CARendererLayerTree::ContentsForSolidColorForTesting(SkColor color) {
+ return SolidColorContents::Get(color)->GetContents();
+}
CARendererLayerTree::RootLayer::RootLayer() {}
@@ -289,6 +364,17 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest) {
DCHECK(filter == GL_LINEAR || filter == GL_NEAREST);
+ // On Mac OS Sierra, solid color layers are not color color corrected to the
+ // output monitor color space, but IOSurface-backed layers are color
+ // corrected. Note that this is only the case when the CALayers are shared
+ // across processes. To make colors consistent across both solid color and
+ // IOSurface-backed layers, use a cache of solid-color IOSurfaces as contents.
+ // https://crbug.com/633805
+ if (!io_surface && !tree->allow_solid_color_layers_) {
+ solid_color_contents = SolidColorContents::Get(background_color);
+ ContentLayer::contents_rect = gfx::RectF(0, 0, 1, 1);
+ }
+
// Because the root layer has setGeometryFlipped:YES, there is some ambiguity
// about what exactly top and bottom mean. This ambiguity is resolved in
// different ways for solid color CALayers and for CALayers that have content
@@ -301,7 +387,7 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
ca_edge_aa_mask |= kCALayerLeftEdge;
if (edge_aa_mask & GL_CA_LAYER_EDGE_RIGHT_CHROMIUM)
ca_edge_aa_mask |= kCALayerRightEdge;
- if (io_surface) {
+ if (io_surface || solid_color_contents) {
if (edge_aa_mask & GL_CA_LAYER_EDGE_TOP_CHROMIUM)
ca_edge_aa_mask |= kCALayerBottomEdge;
if (edge_aa_mask & GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM)
@@ -326,6 +412,7 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
CARendererLayerTree::ContentLayer::ContentLayer(ContentLayer&& layer)
: io_surface(layer.io_surface),
cv_pixel_buffer(layer.cv_pixel_buffer),
+ solid_color_contents(layer.solid_color_contents),
contents_rect(layer.contents_rect),
rect(layer.rect),
background_color(layer.background_color),
@@ -548,7 +635,8 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
std::swap(ca_layer, old_layer->ca_layer);
std::swap(av_layer, old_layer->av_layer);
update_contents = old_layer->io_surface != io_surface ||
- old_layer->cv_pixel_buffer != cv_pixel_buffer;
+ old_layer->cv_pixel_buffer != cv_pixel_buffer ||
+ old_layer->solid_color_contents != solid_color_contents;
update_contents_rect = old_layer->contents_rect != contents_rect;
update_rect = old_layer->rect != rect;
update_background_color = old_layer->background_color != background_color;
@@ -585,7 +673,13 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
}
} else {
if (update_contents) {
- [ca_layer setContents:static_cast<id>(io_surface.get())];
+ if (io_surface) {
+ [ca_layer setContents:static_cast<id>(io_surface.get())];
+ } else if (solid_color_contents) {
+ [ca_layer setContents:solid_color_contents->GetContents()];
+ } else {
+ [ca_layer setContents:nil];
+ }
if ([ca_layer respondsToSelector:(@selector(setContentsScale:))])
[ca_layer setContentsScale:scale_factor];
}
@@ -626,9 +720,15 @@ bool AVSampleBufferDisplayLayerEnqueueIOSurface(
if (use_av_layer) {
// Yellow represents an AV layer that changed this frame.
color.reset(CGColorCreateGenericRGB(1, 1, 0, 1));
- } else {
- // Pink represents a CALayer that changed this frame.
+ } else if (io_surface) {
+ // Magenta represents a CALayer that changed this frame.
color.reset(CGColorCreateGenericRGB(1, 0, 1, 1));
+ } else if (solid_color_contents) {
+ // Cyan represents a solid color IOSurface-backed layer.
+ color.reset(CGColorCreateGenericRGB(0, 1, 1, 1));
+ } else {
+ // Red represents a solid color layer.
+ color.reset(CGColorCreateGenericRGB(1, 0, 0, 1));
}
} else {
// Grey represents a CALayer that has not changed.
« no previous file with comments | « ui/accelerated_widget_mac/ca_renderer_layer_tree.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698