| Index: ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
|
| diff --git a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
|
| index 882fc8c887d52e2aa6d0ab9461a76017caae1176..91283677e3cd00cc827204400dbf423a7505b1a9 100644
|
| --- a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
|
| +++ b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
|
| @@ -13,12 +13,20 @@
|
| #include "ui/accelerated_widget_mac/ca_renderer_layer_tree.h"
|
| #include "ui/gfx/geometry/dip_util.h"
|
| #include "ui/gfx/mac/io_surface.h"
|
| +#include "ui/gl/ca_renderer_layer_params.h"
|
| +#include "ui/gl/gl_image_io_surface.h"
|
|
|
| namespace gpu {
|
|
|
| namespace {
|
|
|
| struct CALayerProperties {
|
| + CALayerProperties() {}
|
| + ~CALayerProperties() {
|
| + if (gl_image)
|
| + gl_image->Destroy(true);
|
| + }
|
| +
|
| bool is_clipped = true;
|
| gfx::Rect clip_rect;
|
| int sorting_context_id = 0;
|
| @@ -30,18 +38,36 @@
|
| float opacity = 1.0f;
|
| float scale_factor = 1.0f;
|
| unsigned filter = GL_LINEAR;
|
| - base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer;
|
| - base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
|
| + scoped_refptr<gl::GLImageIOSurface> gl_image;
|
| };
|
|
|
| +scoped_refptr<gl::GLImageIOSurface> CreateGLImage(const gfx::Size& size,
|
| + gfx::BufferFormat format,
|
| + bool video) {
|
| + scoped_refptr<gl::GLImageIOSurface> gl_image(
|
| + new gl::GLImageIOSurface(size, GL_RGBA));
|
| + base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
|
| + gfx::CreateIOSurface(size, format));
|
| + if (video) {
|
| + base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer;
|
| + CVPixelBufferCreateWithIOSurface(nullptr, io_surface, nullptr,
|
| + cv_pixel_buffer.InitializeInto());
|
| + gl_image->InitializeWithCVPixelBuffer(cv_pixel_buffer,
|
| + gfx::GenericSharedMemoryId(), format);
|
| + } else {
|
| + gl_image->Initialize(io_surface, gfx::GenericSharedMemoryId(), format);
|
| + }
|
| + return gl_image;
|
| +}
|
| +
|
| bool ScheduleCALayer(ui::CARendererLayerTree* tree,
|
| CALayerProperties* properties) {
|
| - return tree->ScheduleCALayer(
|
| + return tree->ScheduleCALayer(ui::CARendererLayerParams(
|
| properties->is_clipped, properties->clip_rect,
|
| properties->sorting_context_id, properties->transform,
|
| - properties->io_surface, properties->cv_pixel_buffer,
|
| - properties->contents_rect, properties->rect, properties->background_color,
|
| - properties->edge_aa_mask, properties->opacity, properties->filter);
|
| + properties->gl_image.get(), properties->contents_rect, properties->rect,
|
| + properties->background_color, properties->edge_aa_mask,
|
| + properties->opacity, properties->filter));
|
| }
|
|
|
| void UpdateCALayerTree(std::unique_ptr<ui::CARendererLayerTree>& ca_layer_tree,
|
| @@ -80,8 +106,8 @@ void SetUp() override {
|
| properties.background_color = SkColorSetARGB(0xFF, 0xFF, 0, 0);
|
| properties.edge_aa_mask = GL_CA_LAYER_EDGE_LEFT_CHROMIUM;
|
| properties.opacity = 0.5f;
|
| - properties.io_surface.reset(
|
| - gfx::CreateIOSurface(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888));
|
| + properties.gl_image =
|
| + CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
|
|
|
| std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
|
| CALayer* root_layer = nil;
|
| @@ -124,7 +150,7 @@ void SetUp() override {
|
| [transform_layer sublayerTransform].m42);
|
|
|
| // Validate the content layer.
|
| - EXPECT_EQ(static_cast<id>(properties.io_surface.get()),
|
| + EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
|
| [content_layer contents]);
|
| EXPECT_EQ(properties.contents_rect,
|
| gfx::RectF([content_layer contentsRect]));
|
| @@ -231,7 +257,8 @@ void SetUp() override {
|
|
|
| // Change the contents and commit.
|
| {
|
| - properties.io_surface.reset();
|
| + properties.gl_image->Destroy(true);
|
| + properties.gl_image = nullptr;
|
| UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
|
|
|
| // Validate the tree structure.
|
| @@ -338,9 +365,8 @@ void SetUp() override {
|
| // Add the clipping and IOSurface contents back.
|
| {
|
| properties.is_clipped = true;
|
| - properties.io_surface.reset(
|
| - gfx::CreateIOSurface(gfx::Size(256, 256),
|
| - gfx::BufferFormat::BGRA_8888));
|
| + properties.gl_image =
|
| + CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
|
| UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
|
|
|
| // Validate the tree structure.
|
| @@ -355,7 +381,7 @@ void SetUp() override {
|
| EXPECT_EQ(content_layer, [[transform_layer sublayers] objectAtIndex:0]);
|
|
|
| // Validate the content layer.
|
| - EXPECT_EQ(static_cast<id>(properties.io_surface.get()),
|
| + EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
|
| [content_layer contents]);
|
| EXPECT_EQ(kCALayerBottomEdge, [content_layer edgeAntialiasingMask]);
|
| }
|
| @@ -400,7 +426,7 @@ void SetUp() override {
|
| [transform_layer sublayerTransform].m42);
|
|
|
| // Validate the content layer.
|
| - EXPECT_EQ(static_cast<id>(properties.io_surface.get()),
|
| + EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
|
| [content_layer contents]);
|
| EXPECT_EQ(properties.contents_rect,
|
| gfx::RectF([content_layer contentsRect]));
|
| @@ -415,6 +441,8 @@ void SetUp() override {
|
| if ([content_layer respondsToSelector:(@selector(contentsScale))])
|
| EXPECT_EQ(properties.scale_factor, [content_layer contentsScale]);
|
| }
|
| +
|
| + properties.gl_image->Destroy(true);
|
| }
|
|
|
| // Verify that sorting context zero is split at non-flat transforms.
|
| @@ -425,10 +453,10 @@ void SetUp() override {
|
| properties.rect = gfx::Rect(0, 0, 256, 256);
|
|
|
| // We'll use the IOSurface contents to identify the content layers.
|
| - base::ScopedCFTypeRef<IOSurfaceRef> io_surfaces[5];
|
| + scoped_refptr<gl::GLImageIOSurface> gl_images[5];
|
| for (size_t i = 0; i < 5; ++i) {
|
| - io_surfaces[i].reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888));
|
| + gl_images[i] =
|
| + CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
|
| }
|
|
|
| // Have 5 transforms:
|
| @@ -446,7 +474,7 @@ void SetUp() override {
|
| std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree(
|
| new ui::CARendererLayerTree);
|
| for (size_t i = 0; i < 5; ++i) {
|
| - properties.io_surface = io_surfaces[i];
|
| + properties.gl_image = gl_images[i];
|
| properties.transform = transforms[i];
|
| bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
|
| EXPECT_TRUE(result);
|
| @@ -494,11 +522,19 @@ void SetUp() override {
|
| CALayer* content_layer_4 = [[transform_layer_2_0 sublayers] objectAtIndex:1];
|
|
|
| // Validate that the layers come out in order.
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[0].get()), [content_layer_0 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[1].get()), [content_layer_1 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[2].get()), [content_layer_2 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[3].get()), [content_layer_3 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[4].get()), [content_layer_4 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[0]->io_surface().get()),
|
| + [content_layer_0 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[1]->io_surface().get()),
|
| + [content_layer_1 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[2]->io_surface().get()),
|
| + [content_layer_2 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[3]->io_surface().get()),
|
| + [content_layer_3 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[4]->io_surface().get()),
|
| + [content_layer_4 contents]);
|
| +
|
| + for (size_t i = 0; i < 5; ++i)
|
| + gl_images[i]->Destroy(true);
|
| }
|
|
|
| // Verify that sorting contexts are allocated appropriately.
|
| @@ -509,10 +545,10 @@ void SetUp() override {
|
| properties.rect = gfx::Rect(0, 0, 256, 256);
|
|
|
| // We'll use the IOSurface contents to identify the content layers.
|
| - base::ScopedCFTypeRef<IOSurfaceRef> io_surfaces[3];
|
| + scoped_refptr<gl::GLImageIOSurface> gl_images[3];
|
| for (size_t i = 0; i < 3; ++i) {
|
| - io_surfaces[i].reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888));
|
| + gl_images[i] =
|
| + CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
|
| }
|
|
|
| int sorting_context_ids[3] = {3, -1, 0};
|
| @@ -522,7 +558,7 @@ void SetUp() override {
|
| new ui::CARendererLayerTree);
|
| for (size_t i = 0; i < 3; ++i) {
|
| properties.sorting_context_id = sorting_context_ids[i];
|
| - properties.io_surface = io_surfaces[i];
|
| + properties.gl_image = gl_images[i];
|
| bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
|
| EXPECT_TRUE(result);
|
| }
|
| @@ -559,9 +595,15 @@ void SetUp() override {
|
| CALayer* content_layer_2 = [[transform_layer_2 sublayers] objectAtIndex:0];
|
|
|
| // Validate that the layers come out in order.
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[0].get()), [content_layer_0 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[1].get()), [content_layer_1 contents]);
|
| - EXPECT_EQ(static_cast<id>(io_surfaces[2].get()), [content_layer_2 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[0]->io_surface().get()),
|
| + [content_layer_0 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[1]->io_surface().get()),
|
| + [content_layer_1 contents]);
|
| + EXPECT_EQ(static_cast<id>(gl_images[2]->io_surface().get()),
|
| + [content_layer_2 contents]);
|
| +
|
| + for (size_t i = 0; i < 3; ++i)
|
| + gl_images[i]->Destroy(true);
|
| }
|
|
|
| // Verify that sorting contexts must all have the same clipping properties.
|
| @@ -614,8 +656,8 @@ void SetUp() override {
|
| // Test updating each layer's properties.
|
| TEST_F(CALayerTreeTest, AVLayer) {
|
| CALayerProperties properties;
|
| - properties.io_surface.reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR));
|
| + properties.gl_image =
|
| + CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
|
|
|
| std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
|
| CALayer* root_layer = nil;
|
| @@ -624,6 +666,7 @@ void SetUp() override {
|
| CALayer* content_layer1 = nil;
|
| CALayer* content_layer2 = nil;
|
| CALayer* content_layer3 = nil;
|
| + CALayer* content_layer4 = nil;
|
|
|
| // Validate the initial values.
|
| {
|
| @@ -644,10 +687,12 @@ void SetUp() override {
|
| isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
|
| }
|
|
|
| - properties.io_surface.reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR));
|
| + properties.gl_image->Destroy(true);
|
| + properties.gl_image = CreateGLImage(
|
| + gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, false);
|
|
|
| - // Pass another frame.
|
| + // Pass another frame. This will automatically create a CVPixelBuffer
|
| + // behind the scenes, because the underlying buffer is YUV 420.
|
| {
|
| UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
|
|
|
| @@ -662,17 +707,16 @@ void SetUp() override {
|
| content_layer2 = [[transform_layer sublayers] objectAtIndex:0];
|
|
|
| // Validate the content layer.
|
| - EXPECT_FALSE([content_layer2
|
| + EXPECT_TRUE([content_layer2
|
| isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
|
| - EXPECT_EQ(content_layer2, content_layer1);
|
| + EXPECT_NE(content_layer2, content_layer1);
|
| }
|
|
|
| - properties.io_surface.reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR));
|
| - CVPixelBufferCreateWithIOSurface(nullptr, properties.io_surface, nullptr,
|
| - properties.cv_pixel_buffer.InitializeInto());
|
| + properties.gl_image->Destroy(true);
|
| + properties.gl_image = CreateGLImage(
|
| + gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, true);
|
|
|
| - // Pass a frame with a CVPixelBuffer
|
| + // Pass a frame with a CVPixelBuffer.
|
| {
|
| UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
|
|
|
| @@ -684,17 +728,17 @@ void SetUp() override {
|
| EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
|
| transform_layer = [[clip_and_sorting_layer sublayers] objectAtIndex:0];
|
| EXPECT_EQ(1u, [[transform_layer sublayers] count]);
|
| - content_layer2 = [[transform_layer sublayers] objectAtIndex:0];
|
| + content_layer3 = [[transform_layer sublayers] objectAtIndex:0];
|
|
|
| // Validate the content layer.
|
| - EXPECT_TRUE([content_layer2
|
| + EXPECT_TRUE([content_layer3
|
| isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
|
| - EXPECT_NE(content_layer2, content_layer1);
|
| + EXPECT_EQ(content_layer3, content_layer2);
|
| }
|
|
|
| - properties.io_surface.reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR));
|
| - properties.cv_pixel_buffer.reset();
|
| + properties.gl_image->Destroy(true);
|
| + properties.gl_image = CreateGLImage(
|
| + gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, false);
|
|
|
| // Pass a frame that is clipped.
|
| properties.contents_rect = gfx::RectF(0, 0, 1, 0.9);
|
| @@ -709,23 +753,21 @@ void SetUp() override {
|
| EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
|
| transform_layer = [[clip_and_sorting_layer sublayers] objectAtIndex:0];
|
| EXPECT_EQ(1u, [[transform_layer sublayers] count]);
|
| - content_layer3 = [[transform_layer sublayers] objectAtIndex:0];
|
| + content_layer4 = [[transform_layer sublayers] objectAtIndex:0];
|
|
|
| // Validate the content layer.
|
| - EXPECT_FALSE([content_layer3
|
| + EXPECT_FALSE([content_layer4
|
| isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
|
| - EXPECT_NE(content_layer3, content_layer2);
|
| + EXPECT_NE(content_layer4, content_layer3);
|
| }
|
| }
|
|
|
| // Test fullscreen low power detection.
|
| TEST_F(CALayerTreeTest, FullscreenLowPower) {
|
| CALayerProperties properties;
|
| - properties.io_surface.reset(gfx::CreateIOSurface(
|
| - gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR));
|
| + properties.gl_image = CreateGLImage(
|
| + gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, true);
|
| properties.is_clipped = false;
|
| - CVPixelBufferCreateWithIOSurface(nullptr, properties.io_surface, nullptr,
|
| - properties.cv_pixel_buffer.InitializeInto());
|
|
|
| CALayerProperties properties_black;
|
| properties_black.is_clipped = false;
|
|
|