| Index: cc/output/renderer_pixeltest.cc
|
| diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
|
| index ffd204a9be180a56ad2ea8bdebc8a2d2bca96e0c..e485a1b30a6af96baa46ee6d6c78aebc6a575b34 100644
|
| --- a/cc/output/renderer_pixeltest.cc
|
| +++ b/cc/output/renderer_pixeltest.cc
|
| @@ -7,6 +7,7 @@
|
| #include <memory>
|
|
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/strings/string_split.h"
|
| #include "cc/base/math_util.h"
|
| #include "cc/output/gl_renderer.h"
|
| #include "cc/quads/draw_quad.h"
|
| @@ -16,6 +17,7 @@
|
| #include "cc/test/fake_raster_source.h"
|
| #include "cc/test/fake_recording_source.h"
|
| #include "cc/test/pixel_test.h"
|
| +#include "cc/test/test_in_process_context_provider.h"
|
| #include "gpu/command_buffer/client/gles2_interface.h"
|
| #include "media/base/video_frame.h"
|
| #include "third_party/skia/include/core/SkColorPriv.h"
|
| @@ -217,72 +219,85 @@ void CreateTestYUVVideoDrawQuad_FromVideoFrame(
|
| video_frame->rows(media::VideoFrame::kAPlane));
|
| }
|
|
|
| - VideoFrameExternalResources resources =
|
| + VideoFrameExternalResources external_resources =
|
| video_resource_updater->CreateExternalResourcesFromVideoFrame(
|
| video_frame);
|
|
|
| - EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
|
| - EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
|
| - resources.mailboxes.size());
|
| - EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
|
| - resources.release_callbacks.size());
|
| -
|
| - ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
|
| - resources.mailboxes[media::VideoFrame::kYPlane],
|
| - SingleReleaseCallbackImpl::Create(
|
| - resources.release_callbacks[media::VideoFrame::kYPlane]));
|
| - ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
|
| - resources.mailboxes[media::VideoFrame::kUPlane],
|
| - SingleReleaseCallbackImpl::Create(
|
| - resources.release_callbacks[media::VideoFrame::kUPlane]));
|
| - ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
|
| - resources.mailboxes[media::VideoFrame::kVPlane],
|
| - SingleReleaseCallbackImpl::Create(
|
| - resources.release_callbacks[media::VideoFrame::kVPlane]));
|
| - ResourceId a_resource = 0;
|
| - if (with_alpha) {
|
| - a_resource = resource_provider->CreateResourceFromTextureMailbox(
|
| - resources.mailboxes[media::VideoFrame::kAPlane],
|
| - SingleReleaseCallbackImpl::Create(
|
| - resources.release_callbacks[media::VideoFrame::kAPlane]));
|
| - }
|
| -
|
| - const gfx::Size ya_tex_size = video_frame->coded_size();
|
| - const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
|
| - video_frame->format(), media::VideoFrame::kUPlane,
|
| - video_frame->coded_size());
|
| - DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
|
| - video_frame->format(), media::VideoFrame::kVPlane,
|
| - video_frame->coded_size()));
|
| - if (with_alpha) {
|
| - DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
|
| - video_frame->format(), media::VideoFrame::kAPlane,
|
| - video_frame->coded_size()));
|
| + ResourceProvider::ResourceIdArray resource_ids;
|
| + resource_ids.reserve(external_resources.mailboxes.size());
|
| + for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) {
|
| + ResourceId resource_id =
|
| + resource_provider->CreateResourceFromTextureMailbox(
|
| + external_resources.mailboxes[i],
|
| + SingleReleaseCallbackImpl::Create(
|
| + external_resources.release_callbacks[i]),
|
| + external_resources.read_lock_fences_enabled);
|
| + resource_ids.push_back(resource_id);
|
| }
|
|
|
| - gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
|
| - tex_coord_rect.y() * ya_tex_size.height(),
|
| - tex_coord_rect.width() * ya_tex_size.width(),
|
| - tex_coord_rect.height() * ya_tex_size.height());
|
| - gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(),
|
| - tex_coord_rect.y() * uv_tex_size.height(),
|
| - tex_coord_rect.width() * uv_tex_size.width(),
|
| - tex_coord_rect.height() * uv_tex_size.height());
|
| -
|
| - YUVVideoDrawQuad* yuv_quad =
|
| - render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
|
| - uint32_t bits_per_channel = 8;
|
| - if (video_frame->format() == media::PIXEL_FORMAT_YUV420P10 ||
|
| - video_frame->format() == media::PIXEL_FORMAT_YUV422P10 ||
|
| - video_frame->format() == media::PIXEL_FORMAT_YUV444P10) {
|
| - bits_per_channel = 10;
|
| + switch (external_resources.type) {
|
| + case VideoFrameExternalResources::YUV_RESOURCE: {
|
| + EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
|
| + external_resources.mailboxes.size());
|
| + EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
|
| + external_resources.release_callbacks.size());
|
| + const gfx::Size ya_tex_size = video_frame->coded_size();
|
| + const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
|
| + video_frame->format(), media::VideoFrame::kUPlane,
|
| + video_frame->coded_size());
|
| + DCHECK(uv_tex_size ==
|
| + media::VideoFrame::PlaneSize(video_frame->format(),
|
| + media::VideoFrame::kVPlane,
|
| + video_frame->coded_size()));
|
| + if (with_alpha) {
|
| + DCHECK(ya_tex_size ==
|
| + media::VideoFrame::PlaneSize(video_frame->format(),
|
| + media::VideoFrame::kAPlane,
|
| + video_frame->coded_size()));
|
| + }
|
| + gfx::RectF ya_tex_coord_rect(
|
| + tex_coord_rect.x() * ya_tex_size.width(),
|
| + tex_coord_rect.y() * ya_tex_size.height(),
|
| + tex_coord_rect.width() * ya_tex_size.width(),
|
| + tex_coord_rect.height() * ya_tex_size.height());
|
| + gfx::RectF uv_tex_coord_rect(
|
| + tex_coord_rect.x() * uv_tex_size.width(),
|
| + tex_coord_rect.y() * uv_tex_size.height(),
|
| + tex_coord_rect.width() * uv_tex_size.width(),
|
| + tex_coord_rect.height() * uv_tex_size.height());
|
| +
|
| + YUVVideoDrawQuad* yuv_quad =
|
| + render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
|
| + yuv_quad->SetNew(
|
| + shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect,
|
| + uv_tex_coord_rect, ya_tex_size, uv_tex_size, resource_ids[0],
|
| + resource_ids[1],
|
| + resource_ids.size() > 2 ? resource_ids[2] : resource_ids[1],
|
| + resource_ids.size() > 3 ? resource_ids[3] : 0, color_space,
|
| + video_color_space, external_resources.offset,
|
| + external_resources.multiplier, external_resources.bits_per_channel);
|
| + break;
|
| + }
|
| + case VideoFrameExternalResources::RGBA_RESOURCE: {
|
| + EXPECT_EQ(1u, external_resources.mailboxes.size());
|
| + EXPECT_EQ(1u, external_resources.release_callbacks.size());
|
| + float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
| + TextureDrawQuad* texture_quad =
|
| + render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
|
| + texture_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
|
| + resource_ids[0], false, tex_coord_rect.origin(),
|
| + tex_coord_rect.bottom_right(), SK_ColorTRANSPARENT,
|
| + opacity, false, false, false);
|
| + break;
|
| + }
|
| + case VideoFrameExternalResources::NONE:
|
| + case VideoFrameExternalResources::RGB_RESOURCE:
|
| + case VideoFrameExternalResources::RGBA_PREMULTIPLIED_RESOURCE:
|
| + case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE:
|
| + case VideoFrameExternalResources::SOFTWARE_RESOURCE:
|
| + NOTREACHED();
|
| + break;
|
| }
|
| -
|
| - yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
|
| - ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
|
| - uv_tex_size, y_resource, u_resource, v_resource, a_resource,
|
| - color_space, video_color_space, 0.0f, 1.0f,
|
| - bits_per_channel);
|
| }
|
|
|
| void CreateTestY16TextureDrawQuad_FromVideoFrame(
|
| @@ -309,7 +324,7 @@ void CreateTestY16TextureDrawQuad_FromVideoFrame(
|
| TextureDrawQuad* quad =
|
| render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
|
| float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
| - quad->SetNew(shared_state, rect, gfx::Rect(), rect, y_resource, false,
|
| + quad->SetNew(shared_state, rect, gfx::Rect(), visible_rect, y_resource, false,
|
| tex_coord_rect.origin(), tex_coord_rect.bottom_right(),
|
| SK_ColorBLACK, vertex_opacity, false, false, false);
|
| }
|
| @@ -372,6 +387,8 @@ void CreateTestYUVVideoDrawQuad_Striped(
|
| ResourceProvider* resource_provider) {
|
| scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
|
| format, rect.size(), rect, rect.size(), base::TimeDelta());
|
| + video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
|
| + media::COLOR_SPACE_JPEG);
|
|
|
| // YUV values representing a striped pattern, for validating texture
|
| // coordinates for sampling.
|
| @@ -515,6 +532,7 @@ void CreateTestYUVVideoDrawQuad_Solid(
|
| void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
|
| media::ColorSpace video_frame_color_space,
|
| const gfx::ColorSpace& video_color_space,
|
| + ResourceFormat y_format,
|
| const gfx::RectF& tex_coord_rect,
|
| uint8_t y,
|
| uint8_t u,
|
| @@ -534,8 +552,8 @@ void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
|
| media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size());
|
|
|
| ResourceId y_resource = resource_provider->CreateResource(
|
| - rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT,
|
| - resource_provider->YuvResourceFormat(8), gfx::ColorSpace());
|
| + rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, y_format,
|
| + gfx::ColorSpace());
|
| ResourceId u_resource = resource_provider->CreateResource(
|
| uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888,
|
| gfx::ColorSpace());
|
| @@ -1195,12 +1213,71 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
|
| output_surface_->context_provider(), resource_provider_.get()));
|
| }
|
|
|
| + void DisableOneComponentTextures() {
|
| + TestInProcessContextProvider* context_provider =
|
| + GetTestInProcessContextProvider();
|
| + context_provider->SetDisableOneComponentTextures(true);
|
| + }
|
| +
|
| std::unique_ptr<VideoResourceUpdater> video_resource_updater_;
|
| +
|
| + protected:
|
| + TestInProcessContextProvider* GetTestInProcessContextProvider() {
|
| + return static_cast<TestInProcessContextProvider*>(
|
| + output_surface_->context_provider());
|
| + }
|
| +};
|
| +
|
| +enum class HighbitTexture {
|
| + Y8,
|
| + RGBA_8888,
|
| + LUMINANCE_F16, // need --use-gpu-in-tests
|
| };
|
|
|
| class VideoGLRendererPixelHiLoTest
|
| : public VideoGLRendererPixelTest,
|
| - public ::testing::WithParamInterface<bool> {};
|
| + public ::testing::WithParamInterface<
|
| + ::testing::tuple<bool, HighbitTexture>> {
|
| + public:
|
| + void SetSupportHighbitTexture(HighbitTexture texture) {
|
| + TestInProcessContextProvider* context_provider =
|
| + GetTestInProcessContextProvider();
|
| + switch (texture) {
|
| + case HighbitTexture::Y8:
|
| + context_provider->SetDisableOneComponentTextures(false);
|
| + context_provider->SetSupportTextureHalfFloatLinear(false);
|
| + break;
|
| + case HighbitTexture::RGBA_8888:
|
| + context_provider->SetDisableOneComponentTextures(true);
|
| + context_provider->SetSupportTextureHalfFloatLinear(false);
|
| + break;
|
| + case HighbitTexture::LUMINANCE_F16:
|
| + context_provider->SetDisableOneComponentTextures(false);
|
| + context_provider->SetSupportTextureHalfFloatLinear(true);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + bool IsHalfFloatLinearSupported() {
|
| + if (extensions_.empty())
|
| + InitializeExtensions();
|
| +
|
| + return extensions_.find("GL_OES_texture_half_float_linear") !=
|
| + extensions_.end();
|
| + }
|
| +
|
| + private:
|
| + void InitializeExtensions() {
|
| + std::string extensions = GetTestInProcessContextProvider()
|
| + ->ContextGL()
|
| + ->GetRequestableExtensionsCHROMIUM();
|
| + std::vector<std::string> tokens = base::SplitString(
|
| + extensions, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| + extensions_.insert(tokens.begin(), tokens.end());
|
| + }
|
| +
|
| + std::set<std::string> extensions_;
|
| +};
|
|
|
| TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
|
| gfx::Rect rect(this->device_viewport_size_);
|
| @@ -1211,7 +1288,12 @@ TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
|
| SharedQuadState* shared_state =
|
| CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
|
|
|
| - bool highbit = GetParam();
|
| + const bool highbit = testing::get<0>(GetParam());
|
| + const HighbitTexture format = testing::get<1>(GetParam());
|
| + if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
|
| + return;
|
| +
|
| + SetSupportHighbitTexture(format);
|
| CreateTestYUVVideoDrawQuad_Striped(
|
| shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
|
| gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
|
| @@ -1220,10 +1302,19 @@ TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
|
| RenderPassList pass_list;
|
| pass_list.push_back(std::move(pass));
|
|
|
| - EXPECT_TRUE(
|
| - this->RunPixelTest(&pass_list,
|
| - base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
|
| - FuzzyPixelOffByOneComparator(true)));
|
| + base::FilePath file_path =
|
| + base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png"));
|
| + // TODO(dshwang): investigate why results per configuraion are so different.
|
| + // crbug.com/622133
|
| + if (format == HighbitTexture::RGBA_8888) {
|
| + // Color space is so different, because this path doesn't respect video
|
| + // color profile.
|
| + file_path = base::FilePath(FILE_PATH_LITERAL("yuv_stripes_rgba.png"));
|
| + }
|
| + EXPECT_TRUE(this->RunPixelTest(
|
| + &pass_list, file_path,
|
| + // All pixels can be off by two, but any more than that is an error.
|
| + FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
|
| }
|
|
|
| TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
|
| @@ -1237,7 +1328,12 @@ TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
|
| SharedQuadState* shared_state =
|
| CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
|
|
|
| - bool highbit = GetParam();
|
| + const bool highbit = testing::get<0>(GetParam());
|
| + const HighbitTexture format = testing::get<1>(GetParam());
|
| + if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
|
| + return;
|
| +
|
| + SetSupportHighbitTexture(format);
|
| CreateTestYUVVideoDrawQuad_Striped(
|
| shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
|
| gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
|
| @@ -1246,9 +1342,16 @@ TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
|
| RenderPassList pass_list;
|
| pass_list.push_back(std::move(pass));
|
|
|
| + base::FilePath file_path =
|
| + base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png"));
|
| + if (format == HighbitTexture::RGBA_8888) {
|
| + file_path =
|
| + base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped_rgba.png"));
|
| + }
|
| EXPECT_TRUE(this->RunPixelTest(
|
| - &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
|
| - FuzzyPixelOffByOneComparator(true)));
|
| + &pass_list, file_path,
|
| + // All pixels can be off by two, but any more than that is an error.
|
| + FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
|
| }
|
|
|
| TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
|
| @@ -1300,7 +1403,13 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
|
| }
|
|
|
| // First argument (test case prefix) is intentionally left empty.
|
| -INSTANTIATE_TEST_CASE_P(, VideoGLRendererPixelHiLoTest, ::testing::Bool());
|
| +INSTANTIATE_TEST_CASE_P(
|
| + ,
|
| + VideoGLRendererPixelHiLoTest,
|
| + ::testing::Combine(::testing::Bool(),
|
| + ::testing::Values(HighbitTexture::Y8,
|
| + HighbitTexture::LUMINANCE_F16,
|
| + HighbitTexture::RGBA_8888)));
|
|
|
| TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
|
| gfx::Rect rect(this->device_viewport_size_);
|
| @@ -1334,11 +1443,14 @@ TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) {
|
| SharedQuadState* shared_state =
|
| CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
|
|
|
| + ResourceFormat y_format =
|
| + video_resource_updater_->YuvResourceFormat(8, media::PIXEL_FORMAT_NV12);
|
| +
|
| // YUV of (149,43,21) should be green (0,255,0) in RGB.
|
| CreateTestYUVVideoDrawQuad_NV12(
|
| shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(),
|
| - gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect,
|
| - resource_provider_.get());
|
| + y_format, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
|
| + rect, rect, resource_provider_.get());
|
|
|
| RenderPassList pass_list;
|
| pass_list.push_back(std::move(pass));
|
| @@ -1368,6 +1480,18 @@ TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
|
| FuzzyPixelOffByOneComparator(true)));
|
| }
|
|
|
| +TEST_F(VideoGLRendererPixelTest, TextureQuadEdgeBleed) {
|
| + // VideoResourceUpdater::CreateForSoftwarePlanes() converts YUV frame to RGBA
|
| + // texture.
|
| + DisableOneComponentTextures();
|
| + RenderPassList pass_list;
|
| + CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
|
| + &pass_list);
|
| + EXPECT_TRUE(this->RunPixelTest(&pass_list,
|
| + base::FilePath(FILE_PATH_LITERAL("green.png")),
|
| + FuzzyPixelOffByOneComparator(true)));
|
| +}
|
| +
|
| TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
|
| gfx::Rect rect(this->device_viewport_size_);
|
|
|
|
|