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

Unified Diff: content/common/gpu/image_transport_surface_overlay_mac.mm

Issue 1409193007: gpu: Add CHROMIUM_schedule_ca_layer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporate review feedback Created 5 years, 1 month 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
Index: content/common/gpu/image_transport_surface_overlay_mac.mm
diff --git a/content/common/gpu/image_transport_surface_overlay_mac.mm b/content/common/gpu/image_transport_surface_overlay_mac.mm
index c7639cb53dff3ebc1c0a58e7153f7d660ea1017a..e4fb3e86c777bc9cf7a75cc306a3c54f6aa56a9d 100644
--- a/content/common/gpu/image_transport_surface_overlay_mac.mm
+++ b/content/common/gpu/image_transport_surface_overlay_mac.mm
@@ -5,6 +5,7 @@
#include "content/common/gpu/image_transport_surface_overlay_mac.h"
#include <algorithm>
+#include <CoreGraphics/CoreGraphics.h>
#include <IOSurface/IOSurface.h>
#include <OpenGL/CGLRenderers.h>
#include <OpenGL/CGLTypes.h>
@@ -26,6 +27,7 @@ typedef void* GLeglImageOES;
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/geometry/dip_util.h"
+#include "ui/gfx/transform.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_image_io_surface.h"
@@ -74,10 +76,6 @@ void CheckGLErrors(const char* msg) {
void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) {
}
-gfx::RectF ConvertRectToDIPF(float scale_factor, const gfx::Rect& rect) {
- return gfx::ScaleRect(gfx::RectF(rect), 1.0f / scale_factor);
-}
-
} // namespace
@interface CALayer(Private)
@@ -95,17 +93,36 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
class ImageTransportSurfaceOverlayMac::OverlayPlane {
public:
- OverlayPlane(int z_order,
- int io_surface_id,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& dip_frame_rect,
- const gfx::RectF& contents_rect)
- : z_order(z_order),
- io_surface_id(io_surface_id),
- io_surface(io_surface),
- dip_frame_rect(dip_frame_rect),
- contents_rect(contents_rect),
- layer_needs_update(true) {}
+ static linked_ptr<OverlayPlane> CreateWithFrameRect(
+ int z_order,
+ int io_surface_id,
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
+ const gfx::RectF& pixel_frame_rect,
+ const gfx::RectF& contents_rect) {
+ gfx::Transform transform;
+ transform.Translate(pixel_frame_rect.x(), pixel_frame_rect.y());
+ return linked_ptr<OverlayPlane>(
+ new OverlayPlane(z_order, io_surface_id, io_surface, contents_rect, 1.f,
+ base::ScopedCFTypeRef<CGColorRef>(),
+ pixel_frame_rect.size(), transform, pixel_frame_rect));
+ }
+
+ static linked_ptr<OverlayPlane> CreateWithTransform(
+ int z_order,
+ int io_surface_id,
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
+ const gfx::RectF& contents_rect,
+ float opacity,
+ base::ScopedCFTypeRef<CGColorRef> background_color,
+ const gfx::SizeF& bounds_size,
+ const gfx::Transform& transform) {
+ gfx::RectF pixel_frame_rect = gfx::RectF(bounds_size);
+ transform.TransformRect(&pixel_frame_rect);
+ return linked_ptr<OverlayPlane>(new OverlayPlane(
+ z_order, io_surface_id, io_surface, contents_rect, opacity,
+ background_color, bounds_size, transform, pixel_frame_rect));
+ }
+
~OverlayPlane() { DCHECK(!ca_layer); }
const int z_order;
@@ -114,8 +131,13 @@ class ImageTransportSurfaceOverlayMac::OverlayPlane {
// The IOSurface to set the CALayer's contents to.
const int io_surface_id;
const base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
- const gfx::RectF dip_frame_rect;
const gfx::RectF contents_rect;
+ float opacity;
+ const base::ScopedCFTypeRef<CGColorRef> background_color;
+ const gfx::SizeF bounds_size;
+ const gfx::Transform transform;
+
+ const gfx::RectF pixel_frame_rect;
bool layer_needs_update;
@@ -131,14 +153,27 @@ class ImageTransportSurfaceOverlayMac::OverlayPlane {
void UpdateProperties() {
if (layer_needs_update) {
[ca_layer setOpaque:YES];
- [ca_layer setFrame:dip_frame_rect.ToCGRect()];
- [ca_layer setContentsRect:contents_rect.ToCGRect()];
+
id new_contents = static_cast<id>(io_surface.get());
if ([ca_layer contents] == new_contents && z_order == 0) {
[ca_layer setContentsChanged];
} else {
[ca_layer setContents:new_contents];
}
+ [ca_layer setContentsRect:contents_rect.ToCGRect()];
+
+ [ca_layer setOpacity:opacity];
+ if (background_color) {
+ [ca_layer setBackgroundColor:background_color];
+ } else {
+ [ca_layer setBackgroundColor:CGColorGetConstantColor(kCGColorClear)];
+ }
+
+ [ca_layer setAnchorPoint:CGPointZero];
+ [ca_layer setBounds:gfx::RectF(bounds_size).ToCGRect()];
+ CATransform3D ca_transform;
+ transform.matrix().asColMajord(&ca_transform.m11);
+ [ca_layer setTransform:ca_transform];
}
static bool show_borders =
base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -155,7 +190,7 @@ class ImageTransportSurfaceOverlayMac::OverlayPlane {
// Red represents damaged contents.
color.reset(CGColorCreateGenericRGB(1, 0, 0, 1));
}
- [ca_layer setBorderWidth:2];
+ [ca_layer setBorderWidth:1];
[ca_layer setBorderColor:color];
}
layer_needs_update = false;
@@ -166,8 +201,32 @@ class ImageTransportSurfaceOverlayMac::OverlayPlane {
return;
[ca_layer setContents:nil];
[ca_layer removeFromSuperlayer];
+ [ca_layer setBorderWidth:0];
+ [ca_layer setBorderColor:CGColorGetConstantColor(kCGColorClear)];
+ [ca_layer setBackgroundColor:CGColorGetConstantColor(kCGColorClear)];
ca_layer.reset();
}
+
+ private:
+ OverlayPlane(int z_order,
+ int io_surface_id,
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
+ const gfx::RectF& contents_rect,
+ float opacity,
+ base::ScopedCFTypeRef<CGColorRef> background_color,
+ const gfx::SizeF& bounds_size,
+ const gfx::Transform& transform,
+ const gfx::RectF& pixel_frame_rect)
+ : z_order(z_order),
+ io_surface_id(io_surface_id),
+ io_surface(io_surface),
+ contents_rect(contents_rect),
+ opacity(opacity),
+ background_color(background_color),
+ bounds_size(bounds_size),
+ transform(transform),
+ pixel_frame_rect(pixel_frame_rect),
+ layer_needs_update(true) {}
};
class ImageTransportSurfaceOverlayMac::PendingSwap {
@@ -205,6 +264,7 @@ ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
scale_factor_(1),
gl_renderer_id_(0),
vsync_parameters_valid_(false),
+ next_ca_layer_z_order_(1),
display_pending_swap_timer_(true, false),
weak_factory_(this) {
helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
@@ -255,6 +315,7 @@ bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
const gfx::Rect& pixel_damage_rect) {
TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal");
+ next_ca_layer_z_order_ = 1;
// Use the same concept of 'now' for the entire function. The duration of
// this function only affect the result if this function lasts across a vsync
@@ -370,15 +431,14 @@ void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
{
// Sort the input planes by z-index, and remove any overlays from the
// damage rect.
- gfx::RectF dip_damage_rect = ConvertRectToDIPF(
- swap->scale_factor, swap->pixel_damage_rect);
+ gfx::RectF pixel_damage_rect = gfx::RectF(swap->pixel_damage_rect);
std::sort(swap->overlay_planes.begin(), swap->overlay_planes.end(),
OverlayPlane::Compare);
for (auto& plane : swap->overlay_planes)
- dip_damage_rect.Subtract(plane->dip_frame_rect);
+ pixel_damage_rect.Subtract(plane->pixel_frame_rect);
ScopedCAActionDisabler disabler;
- UpdateRootAndPartialDamagePlanes(swap->root_plane, dip_damage_rect);
+ UpdateRootAndPartialDamagePlanes(swap->root_plane, pixel_damage_rect);
UpdateOverlayPlanes(swap->overlay_planes);
UpdateCALayerTree();
swap->overlay_planes.clear();
@@ -435,7 +495,7 @@ void ImageTransportSurfaceOverlayMac::UpdateOverlayPlanes(
void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
const linked_ptr<OverlayPlane>& new_root_plane,
- const gfx::RectF& dip_damage_rect) {
+ const gfx::RectF& pixel_damage_rect) {
std::list<linked_ptr<OverlayPlane>> old_partial_damage_planes;
old_partial_damage_planes.swap(current_partial_damage_planes_);
linked_ptr<OverlayPlane> plane_for_swap;
@@ -454,14 +514,15 @@ void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
// we have full damage, or if we don't support remote layers, then use the
// root layer directly.
if (!use_remote_layer_api_ || !current_root_plane_.get() ||
- current_root_plane_->dip_frame_rect != new_root_plane->dip_frame_rect ||
- dip_damage_rect == new_root_plane->dip_frame_rect) {
+ current_root_plane_->pixel_frame_rect !=
+ new_root_plane->pixel_frame_rect ||
+ pixel_damage_rect == new_root_plane->pixel_frame_rect) {
plane_for_swap = new_root_plane;
}
// Walk though the existing partial damage layers and see if there is one that
// is appropriate to re-use.
- if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) {
+ if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty()) {
gfx::RectF plane_to_reuse_dip_enlarged_rect;
// Find the last partial damage plane to re-use the CALayer from. Grow the
@@ -469,13 +530,13 @@ void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
// damage layers.
linked_ptr<OverlayPlane> plane_to_reuse;
for (auto& old_plane : old_partial_damage_planes) {
- gfx::RectF dip_enlarged_rect = old_plane->dip_frame_rect;
- dip_enlarged_rect.Union(dip_damage_rect);
+ gfx::RectF dip_enlarged_rect = old_plane->pixel_frame_rect;
+ dip_enlarged_rect.Union(pixel_damage_rect);
// Compute the fraction of the pixels that would not be updated by this
// swap. If it is too big, try another layer.
float waste_fraction = dip_enlarged_rect.size().GetArea() * 1.f /
- dip_damage_rect.size().GetArea();
+ pixel_damage_rect.size().GetArea();
if (waste_fraction > kMaximumPartialDamageWasteFraction)
continue;
@@ -486,12 +547,12 @@ void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
if (plane_to_reuse.get()) {
gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect;
enlarged_contents_rect.Scale(
- 1. / new_root_plane->dip_frame_rect.width(),
- 1. / new_root_plane->dip_frame_rect.height());
+ 1. / new_root_plane->pixel_frame_rect.width(),
+ 1. / new_root_plane->pixel_frame_rect.height());
- plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane(
+ plane_for_swap = OverlayPlane::CreateWithFrameRect(
0, new_root_plane->io_surface_id, new_root_plane->io_surface,
- plane_to_reuse_dip_enlarged_rect, enlarged_contents_rect));
+ plane_to_reuse_dip_enlarged_rect, enlarged_contents_rect);
plane_for_swap->TakeCALayerFrom(plane_to_reuse.get());
if (plane_to_reuse != old_partial_damage_planes.back())
@@ -501,18 +562,18 @@ void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
// If we haven't found an appropriate layer to re-use, create a new one, if
// we haven't already created too many.
- if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty() &&
+ if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty() &&
old_partial_damage_planes.size() < kMaximumPartialDamageLayers) {
- gfx::RectF contents_rect = gfx::RectF(dip_damage_rect);
- contents_rect.Scale(1. / new_root_plane->dip_frame_rect.width(),
- 1. / new_root_plane->dip_frame_rect.height());
- plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane(
+ gfx::RectF contents_rect = gfx::RectF(pixel_damage_rect);
+ contents_rect.Scale(1. / new_root_plane->pixel_frame_rect.width(),
+ 1. / new_root_plane->pixel_frame_rect.height());
+ plane_for_swap = OverlayPlane::CreateWithFrameRect(
0, new_root_plane->io_surface_id, new_root_plane->io_surface,
- dip_damage_rect, contents_rect));
+ pixel_damage_rect, contents_rect);
}
// And if we still don't have a layer, use the root layer.
- if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty())
+ if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty())
plane_for_swap = new_root_plane;
// Walk all old partial damage planes. Remove anything that is now completely
@@ -521,11 +582,11 @@ void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes(
for (auto& old_plane : old_partial_damage_planes) {
// Intersect the planes' frames with the new root plane to ensure that
// they don't get kept alive inappropriately.
- gfx::RectF old_plane_frame_rect = old_plane->dip_frame_rect;
- old_plane_frame_rect.Intersect(new_root_plane->dip_frame_rect);
+ gfx::RectF old_plane_frame_rect = old_plane->pixel_frame_rect;
+ old_plane_frame_rect.Intersect(new_root_plane->pixel_frame_rect);
if (plane_for_swap.get() &&
- plane_for_swap->dip_frame_rect.Contains(old_plane_frame_rect)) {
+ plane_for_swap->pixel_frame_rect.Contains(old_plane_frame_rect)) {
old_plane->Destroy();
} else {
DCHECK(old_plane->ca_layer);
@@ -588,6 +649,8 @@ void ImageTransportSurfaceOverlayMac::UpdateCALayerTree() {
plane->UpdateProperties();
for (auto& plane : current_overlay_planes_)
plane->UpdateProperties();
+ [ca_root_layer_ setTransform:CATransform3DMakeScale(1 / scale_factor_,
+ 1 / scale_factor_, 1)];
DCHECK_EQ(
static_cast<size_t>([[ca_root_layer_ sublayers] count]),
@@ -674,16 +737,16 @@ bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane(
int z_order,
gfx::OverlayTransform transform,
gl::GLImage* image,
- const gfx::Rect& bounds_rect,
+ const gfx::Rect& pixel_frame_rect,
const gfx::RectF& crop_rect) {
DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
if (transform != gfx::OVERLAY_TRANSFORM_NONE)
return false;
- linked_ptr<OverlayPlane> plane(new OverlayPlane(
+ linked_ptr<OverlayPlane> plane = OverlayPlane::CreateWithFrameRect(
z_order, static_cast<gl::GLImageIOSurface*>(image)->io_surface_id().id,
static_cast<gl::GLImageIOSurface*>(image)->io_surface(),
- ConvertRectToDIPF(scale_factor_, bounds_rect), crop_rect));
+ gfx::RectF(pixel_frame_rect), crop_rect);
if (z_order == 0)
pending_root_plane_ = plane;
else
@@ -692,6 +755,39 @@ bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane(
return true;
}
+bool ImageTransportSurfaceOverlayMac::ScheduleCALayer(
+ gl::GLImage* contents_image,
+ const gfx::RectF& contents_rect,
+ float opacity,
+ unsigned background_color,
+ const gfx::SizeF& bounds_size,
+ const gfx::Transform& transform) {
+ // Extract the IOSurface, if this layer is not just a solid color.
+ int io_surface_id = 0;
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
+ if (contents_image) {
+ io_surface_id =
+ static_cast<gl::GLImageIOSurface*>(contents_image)->io_surface_id().id;
+ io_surface =
+ static_cast<gl::GLImageIOSurface*>(contents_image)->io_surface();
+ }
+
+ // Convert the RGBA SkColor to an sRGB CGColorRef.
+ CGFloat rgba_color_components[4] = {
+ SkColorGetR(background_color) / 255.,
+ SkColorGetG(background_color) / 255.,
+ SkColorGetB(background_color) / 255.,
+ SkColorGetA(background_color) / 255.,
+ };
+ base::ScopedCFTypeRef<CGColorRef> srgb_background_color(CGColorCreate(
+ CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components));
+
+ pending_overlay_planes_.push_back(OverlayPlane::CreateWithTransform(
+ next_ca_layer_z_order_++, io_surface_id, io_surface, contents_rect,
+ opacity, srgb_background_color, bounds_size, transform));
+ return true;
+}
+
bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const {
return true;
}
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | gpu/GLES2/extensions/CHROMIUM/CHROMIUM_schedule_ca_layer.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698