Chromium Code Reviews| Index: cc/output/renderer_pixeltest.cc |
| diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc |
| index c62ae058d00de3a93b6a68d2ecc1a2a8cbc5a1c1..0c0b752b5e5dc5848aa14425b2dd369ff75be061 100644 |
| --- a/cc/output/renderer_pixeltest.cc |
| +++ b/cc/output/renderer_pixeltest.cc |
| @@ -16,6 +16,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 +218,80 @@ 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; |
| + } |
| + default: |
|
enne (OOO)
2016/10/19 19:04:03
style nit: Don't use "default: NOTREACHED" here.
dshwang
2016/10/20 18:57:55
Done.
|
| + NOTREACHED(); |
| } |
| - |
| - 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); |
| } |
| // Upshift video frame to 10 bit. |
| @@ -343,6 +352,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. |
| @@ -486,6 +497,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, |
| @@ -505,8 +517,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()); |
| @@ -1094,12 +1106,51 @@ 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 { |
|
enne (OOO)
2016/10/19 19:04:03
What does HighbitTexture mean? I guess I don't und
dshwang
2016/10/20 18:57:55
I follow this existing naming. e.g. 1113 bool hi
|
| + Y8, |
| + RGBA_8888, |
| + LUMINANCE_F16, |
| }; |
| 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; |
| + } |
| + } |
| +}; |
| TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) { |
| gfx::Rect rect(this->device_viewport_size_); |
| @@ -1110,7 +1161,9 @@ 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()); |
| + SetSupportHighbitTexture(format); |
| CreateTestYUVVideoDrawQuad_Striped( |
| shared_state, media::PIXEL_FORMAT_YV12, false, highbit, |
| gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), |
| @@ -1119,10 +1172,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) { |
| @@ -1136,7 +1198,9 @@ 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()); |
| + SetSupportHighbitTexture(format); |
| CreateTestYUVVideoDrawQuad_Striped( |
| shared_state, media::PIXEL_FORMAT_YV12, false, highbit, |
| gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), |
| @@ -1145,9 +1209,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) { |
| @@ -1199,7 +1270,15 @@ 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, |
| + // LUMINANCE_F16 requires --use-gpu-in-tests |
|
enne (OOO)
2016/10/19 19:04:03
Do we have --use-gpu-in-tests running anywhere? Ca
dshwang
2016/10/20 18:57:56
good idea. Done.
|
| + // HighbitTexture::LUMINANCE_F16, |
| + HighbitTexture::RGBA_8888))); |
| TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { |
| gfx::Rect rect(this->device_viewport_size_); |
| @@ -1233,11 +1312,13 @@ TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) { |
| SharedQuadState* shared_state = |
| CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| + ResourceFormat y_format = video_resource_updater_->YuvResourceFormat(8); |
| + |
| // 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)); |
| @@ -1267,6 +1348,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_); |