summaryrefslogtreecommitdiffstats
path: root/cc/output/renderer_pixeltest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cc/output/renderer_pixeltest.cc')
-rw-r--r--cc/output/renderer_pixeltest.cc812
1 files changed, 558 insertions, 254 deletions
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index b30b0a5..295fc84 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -111,6 +111,52 @@ void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
FilterOperations()); // background filters
}
+void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
+ SkColor texel_color,
+ SkColor texel_stripe_color,
+ SkColor background_color,
+ bool premultiplied_alpha,
+ const SharedQuadState* shared_state,
+ ResourceProvider* resource_provider,
+ RenderPass* render_pass) {
+ SkPMColor pixel_color = premultiplied_alpha
+ ? SkPreMultiplyColor(texel_color)
+ : SkPackARGB32NoCheck(SkColorGetA(texel_color),
+ SkColorGetR(texel_color),
+ SkColorGetG(texel_color),
+ SkColorGetB(texel_color));
+ SkPMColor pixel_stripe_color =
+ premultiplied_alpha
+ ? SkPreMultiplyColor(texel_stripe_color)
+ : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
+ SkColorGetR(texel_stripe_color),
+ SkColorGetG(texel_stripe_color),
+ SkColorGetB(texel_stripe_color));
+ std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
+ for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
+ for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
+ pixels[i * rect.width() + k] = pixel_stripe_color;
+ }
+ }
+ ResourceProvider::ResourceId resource = resource_provider->CreateResource(
+ rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
+ resource_provider->SetPixels(resource,
+ reinterpret_cast<uint8_t*>(&pixels.front()),
+ rect, rect, gfx::Vector2d());
+
+ float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const gfx::PointF uv_top_left(0.0f, 0.0f);
+ const gfx::PointF uv_bottom_right(1.0f, 1.0f);
+ const bool flipped = false;
+ const bool nearest_neighbor = false;
+ TextureDrawQuad* quad =
+ render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
+ quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
+ premultiplied_alpha, uv_top_left, uv_bottom_right,
+ background_color, vertex_opacity, flipped, nearest_neighbor);
+}
+
void CreateTestTextureDrawQuad(const gfx::Rect& rect,
SkColor texel_color,
SkColor background_color,
@@ -135,20 +181,216 @@ void CreateTestTextureDrawQuad(const gfx::Rect& rect,
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const gfx::PointF uv_top_left(0.0f, 0.0f);
+ const gfx::PointF uv_bottom_right(1.0f, 1.0f);
+ const bool flipped = false;
+ const bool nearest_neighbor = false;
TextureDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
- quad->SetNew(shared_state,
- rect,
- gfx::Rect(),
- rect,
- resource,
- premultiplied_alpha,
- gfx::PointF(0.0f, 0.0f), // uv_top_left
- gfx::PointF(1.0f, 1.0f), // uv_bottom_right
- background_color,
- vertex_opacity,
- false, // flipped
- false); // nearest_neighbor
+ quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
+ premultiplied_alpha, uv_top_left, uv_bottom_right,
+ background_color, vertex_opacity, flipped, nearest_neighbor);
+}
+
+void CreateTestYUVVideoDrawQuad_FromVideoFrame(
+ const SharedQuadState* shared_state,
+ scoped_refptr<media::VideoFrame> video_frame,
+ uint8 alpha_value,
+ const gfx::RectF& tex_coord_rect,
+ RenderPass* render_pass,
+ VideoResourceUpdater* video_resource_updater,
+ const gfx::Rect& rect,
+ ResourceProvider* resource_provider) {
+ const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
+ const YUVVideoDrawQuad::ColorSpace color_space =
+ (video_frame->format() == media::VideoFrame::YV12J
+ ? YUVVideoDrawQuad::JPEG
+ : YUVVideoDrawQuad::REC_601);
+ const gfx::Rect opaque_rect(0, 0, 0, 0);
+
+ if (with_alpha) {
+ memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
+ video_frame->stride(media::VideoFrame::kAPlane) *
+ video_frame->rows(media::VideoFrame::kAPlane));
+ }
+
+ VideoFrameExternalResources 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());
+
+ ResourceProvider::ResourceId y_resource =
+ resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kYPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kYPlane]));
+ ResourceProvider::ResourceId u_resource =
+ resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kUPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kUPlane]));
+ ResourceProvider::ResourceId v_resource =
+ resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kVPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kVPlane]));
+ ResourceProvider::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]));
+ }
+
+ YUVVideoDrawQuad* yuv_quad =
+ render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
+ yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
+ video_frame->coded_size(), y_resource, u_resource,
+ v_resource, a_resource, color_space);
+}
+
+void CreateTestYUVVideoDrawQuad_Striped(
+ const SharedQuadState* shared_state,
+ media::VideoFrame::Format format,
+ bool is_transparent,
+ const gfx::RectF& tex_coord_rect,
+ RenderPass* render_pass,
+ VideoResourceUpdater* video_resource_updater,
+ const gfx::Rect& rect,
+ ResourceProvider* resource_provider) {
+ scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
+ format, rect.size(), rect, rect.size(), base::TimeDelta());
+
+ // YUV values representing a striped pattern, for validating texture
+ // coordinates for sampling.
+ uint8_t y_value = 0;
+ uint8_t u_value = 0;
+ uint8_t v_value = 0;
+ for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
+ uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
+ video_frame->stride(media::VideoFrame::kYPlane) * i;
+ for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
+ ++j) {
+ y_row[j] = (y_value += 1);
+ }
+ }
+ for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
+ uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
+ video_frame->stride(media::VideoFrame::kUPlane) * i;
+ uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
+ video_frame->stride(media::VideoFrame::kVPlane) * i;
+ for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
+ ++j) {
+ u_row[j] = (u_value += 3);
+ v_row[j] = (v_value += 5);
+ }
+ }
+ uint8 alpha_value = is_transparent ? 0 : 128;
+ CreateTestYUVVideoDrawQuad_FromVideoFrame(
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
+ video_resource_updater, rect, resource_provider);
+}
+
+// Creates a video frame of size background_size filled with yuv_background,
+// and then draws a foreground rectangle in a different color on top of
+// that. The foreground rectangle must have coordinates that are divisible
+// by 2 because YUV is a block format.
+void CreateTestYUVVideoDrawQuad_TwoColor(
+ const SharedQuadState* shared_state,
+ media::VideoFrame::Format format,
+ bool is_transparent,
+ const gfx::RectF& tex_coord_rect,
+ const gfx::Size& background_size,
+ uint8 y_background,
+ uint8 u_background,
+ uint8 v_background,
+ const gfx::Rect& foreground_rect,
+ uint8 y_foreground,
+ uint8 u_foreground,
+ uint8 v_foreground,
+ RenderPass* render_pass,
+ VideoResourceUpdater* video_resource_updater,
+ ResourceProvider* resource_provider) {
+ const gfx::Rect rect(background_size);
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
+ foreground_rect.size(), base::TimeDelta());
+
+ int planes[] = {media::VideoFrame::kYPlane,
+ media::VideoFrame::kUPlane,
+ media::VideoFrame::kVPlane};
+ uint8 yuv_background[] = {y_background, u_background, v_background};
+ uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
+ int sample_size[] = {1, 2, 2};
+
+ for (int i = 0; i < 3; ++i) {
+ memset(video_frame->data(planes[i]), yuv_background[i],
+ video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ // Since yuv encoding uses block encoding, widths have to be divisible
+ // by the sample size in order for this function to behave properly.
+ DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
+
+ gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
+ foreground_rect.y() / sample_size[i],
+ foreground_rect.width() / sample_size[i],
+ foreground_rect.height() / sample_size[i]);
+ for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
+ for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
+ size_t offset = y * video_frame->stride(planes[i]) + x;
+ video_frame->data(planes[i])[offset] = yuv_foreground[i];
+ }
+ }
+ }
+
+ uint8 alpha_value = 255;
+ CreateTestYUVVideoDrawQuad_FromVideoFrame(
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
+ video_resource_updater, rect, resource_provider);
+}
+
+void CreateTestYUVVideoDrawQuad_Solid(
+ const SharedQuadState* shared_state,
+ media::VideoFrame::Format format,
+ bool is_transparent,
+ const gfx::RectF& tex_coord_rect,
+ uint8 y,
+ uint8 u,
+ uint8 v,
+ RenderPass* render_pass,
+ VideoResourceUpdater* video_resource_updater,
+ const gfx::Rect& rect,
+ ResourceProvider* resource_provider) {
+ scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
+ format, rect.size(), rect, rect.size(), base::TimeDelta());
+
+ // YUV values of a solid, constant, color. Useful for testing that color
+ // space/color range are being handled properly.
+ memset(video_frame->data(media::VideoFrame::kYPlane), y,
+ video_frame->stride(media::VideoFrame::kYPlane) *
+ video_frame->rows(media::VideoFrame::kYPlane));
+ memset(video_frame->data(media::VideoFrame::kUPlane), u,
+ video_frame->stride(media::VideoFrame::kUPlane) *
+ video_frame->rows(media::VideoFrame::kUPlane));
+ memset(video_frame->data(media::VideoFrame::kVPlane), v,
+ video_frame->stride(media::VideoFrame::kVPlane) *
+ video_frame->rows(media::VideoFrame::kVPlane));
+
+ uint8 alpha_value = is_transparent ? 0 : 128;
+ CreateTestYUVVideoDrawQuad_FromVideoFrame(
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
+ video_resource_updater, rect, resource_provider);
}
typedef ::testing::Types<GLRenderer,
@@ -323,6 +565,278 @@ TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
FuzzyPixelOffByOneComparator(true)));
}
+template <typename QuadType>
+static const base::FilePath::CharType* IntersectingQuadImage() {
+ return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
+}
+template <>
+const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
+ return FILE_PATH_LITERAL("intersecting_blue_green.png");
+}
+template <>
+const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
+ return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
+}
+
+template <typename TypeParam>
+class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
+ protected:
+ void SetupQuadStateAndRenderPass() {
+ // This sets up a pair of draw quads. They are both rotated
+ // relative to the root plane, they are also rotated relative to each other.
+ // The intersect in the middle at a non-perpendicular angle so that any
+ // errors are hopefully magnified.
+ // The quads should intersect correctly, as in the front quad should only
+ // be partially in front of the back quad, and partially behind.
+
+ viewport_rect_ = gfx::Rect(this->device_viewport_size_);
+ quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
+ this->device_viewport_size_.height() / 2.0);
+
+ RenderPassId id(1, 1);
+ render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
+
+ // Create the front quad rotated on the Z and Y axis.
+ gfx::Transform trans;
+ trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
+ trans.RotateAboutZAxis(45.0);
+ trans.RotateAboutYAxis(45.0);
+ front_quad_state_ =
+ CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
+ front_quad_state_->clip_rect = quad_rect_;
+ // Make sure they end up in a 3d sorting context.
+ front_quad_state_->sorting_context_id = 1;
+
+ // Create the back quad, and rotate on just the y axis. This will intersect
+ // the first quad partially.
+ trans = gfx::Transform();
+ trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
+ trans.RotateAboutYAxis(-45.0);
+ back_quad_state_ =
+ CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
+ back_quad_state_->sorting_context_id = 1;
+ back_quad_state_->clip_rect = quad_rect_;
+ }
+ template <typename T>
+ void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
+ SharedQuadState* background_quad_state = CreateTestSharedQuadState(
+ gfx::Transform(), viewport_rect_, render_pass_.get());
+ SolidColorDrawQuad* background_quad =
+ render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ background_quad->SetNew(background_quad_state, viewport_rect_,
+ viewport_rect_, SK_ColorWHITE, false);
+ pass_list_.push_back(render_pass_.Pass());
+ const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
+ EXPECT_TRUE(
+ this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
+ }
+ template <typename T>
+ T* CreateAndAppendDrawQuad() {
+ return render_pass_->CreateAndAppendDrawQuad<T>();
+ }
+
+ scoped_ptr<RenderPass> render_pass_;
+ gfx::Rect viewport_rect_;
+ SharedQuadState* front_quad_state_;
+ SharedQuadState* back_quad_state_;
+ gfx::Rect quad_rect_;
+ RenderPassList pass_list_;
+};
+
+template <typename TypeParam>
+class IntersectingQuadGLPixelTest
+ : public IntersectingQuadPixelTest<TypeParam> {
+ public:
+ void SetUp() override {
+ IntersectingQuadPixelTest<TypeParam>::SetUp();
+ video_resource_updater_.reset(
+ new VideoResourceUpdater(this->output_surface_->context_provider(),
+ this->resource_provider_.get()));
+ video_resource_updater2_.reset(
+ new VideoResourceUpdater(this->output_surface_->context_provider(),
+ this->resource_provider_.get()));
+ }
+
+ protected:
+ scoped_ptr<VideoResourceUpdater> video_resource_updater_;
+ scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
+};
+
+template <typename TypeParam>
+class IntersectingQuadSoftwareTest
+ : public IntersectingQuadPixelTest<TypeParam> {};
+
+typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
+ SoftwareRendererTypes;
+typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
+ GLRendererTypes;
+
+TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
+TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
+TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
+
+TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
+ this->SetupQuadStateAndRenderPass();
+
+ SolidColorDrawQuad* quad =
+ this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ SolidColorDrawQuad* quad2 =
+ this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+
+ quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
+ SK_ColorBLUE, false);
+ quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
+ SK_ColorGREEN, false);
+ SCOPED_TRACE("IntersectingSolidColorQuads");
+ this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
+ FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
+}
+
+template <typename TypeParam>
+SkColor GetColor(const SkColor& color) {
+ return color;
+}
+
+template <>
+SkColor GetColor<GLRenderer>(const SkColor& color) {
+ return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
+ SkColorGetG(color), SkColorGetR(color));
+}
+template <>
+SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
+ return GetColor<GLRenderer>(color);
+}
+
+TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
+ this->SetupQuadStateAndRenderPass();
+ CreateTestTwoColoredTextureDrawQuad(
+ this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
+ GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
+ true, this->front_quad_state_, this->resource_provider_.get(),
+ this->render_pass_.get());
+ CreateTestTwoColoredTextureDrawQuad(
+ this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
+ GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
+ true, this->back_quad_state_, this->resource_provider_.get(),
+ this->render_pass_.get());
+
+ SCOPED_TRACE("IntersectingTexturedQuads");
+ this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
+ FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
+}
+
+TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
+ this->SetupQuadStateAndRenderPass();
+ gfx::RectF outer_rect(this->quad_rect_);
+ gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
+ this->quad_rect_.y() + (this->quad_rect_.height() / 4),
+ this->quad_rect_.width() / 2,
+ this->quad_rect_.height() / 2);
+
+ SkPaint black_paint;
+ black_paint.setColor(SK_ColorBLACK);
+ SkPaint blue_paint;
+ blue_paint.setColor(SK_ColorBLUE);
+ SkPaint green_paint;
+ green_paint.setColor(SK_ColorGREEN);
+
+ scoped_ptr<FakePicturePile> blue_recording =
+ FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
+ this->quad_rect_.size());
+ blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
+ blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
+ blue_recording->RerecordPile();
+ scoped_refptr<FakePicturePileImpl> blue_pile =
+ FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
+
+ PictureDrawQuad* blue_quad =
+ this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
+
+ blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
+ this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
+ false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
+
+ scoped_ptr<FakePicturePile> green_recording =
+ FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
+ this->quad_rect_.size());
+ green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
+ green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
+ green_recording->RerecordPile();
+ scoped_refptr<FakePicturePileImpl> green_pile =
+ FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
+
+ PictureDrawQuad* green_quad =
+ this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
+ green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
+ this->quad_rect_, this->quad_rect_,
+ this->quad_rect_.size(), false, RGBA_8888,
+ this->quad_rect_, 1.f, green_pile);
+ SCOPED_TRACE("IntersectingPictureQuadsPass");
+ this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
+ FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
+}
+
+TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
+ this->SetupQuadStateAndRenderPass();
+ RenderPassId child_pass_id1(2, 2);
+ RenderPassId child_pass_id2(2, 3);
+ scoped_ptr<RenderPass> child_pass1 =
+ CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
+ SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
+ gfx::Transform(), this->quad_rect_, child_pass1.get());
+ scoped_ptr<RenderPass> child_pass2 =
+ CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
+ SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
+ gfx::Transform(), this->quad_rect_, child_pass2.get());
+
+ CreateTestTwoColoredTextureDrawQuad(
+ this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
+ GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
+ true, child1_quad_state, this->resource_provider_.get(),
+ child_pass1.get());
+ CreateTestTwoColoredTextureDrawQuad(
+ this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
+ GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
+ true, child2_quad_state, this->resource_provider_.get(),
+ child_pass2.get());
+
+ CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
+ child_pass_id1, this->render_pass_.get());
+ CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
+ child_pass_id2, this->render_pass_.get());
+
+ this->pass_list_.push_back(child_pass1.Pass());
+ this->pass_list_.push_back(child_pass2.Pass());
+ SCOPED_TRACE("IntersectingRenderQuadsPass");
+ this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
+ FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
+}
+
+TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
+ this->SetupQuadStateAndRenderPass();
+ gfx::Rect inner_rect(
+ ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
+ ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
+ (this->quad_rect_.width() / 2) & ~0xF,
+ (this->quad_rect_.height() / 2) & ~0xF);
+
+ CreateTestYUVVideoDrawQuad_TwoColor(
+ this->front_quad_state_, media::VideoFrame::YV12J, false,
+ gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 0, 128, 128,
+ inner_rect, 29, 255, 107, this->render_pass_.get(),
+ this->video_resource_updater_.get(), this->resource_provider_.get());
+
+ CreateTestYUVVideoDrawQuad_TwoColor(
+ this->back_quad_state_, media::VideoFrame::YV12J, false,
+ gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 149, 43, 21,
+ inner_rect, 0, 128, 128, this->render_pass_.get(),
+ this->video_resource_updater2_.get(), this->resource_provider_.get());
+
+ SCOPED_TRACE("IntersectingVideoQuads");
+ this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
+ FuzzyPixelOffByOneComparator(false));
+}
+
// TODO(skaslev): The software renderer does not support non-premultplied alpha.
TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
gfx::Rect rect(this->device_viewport_size_);
@@ -390,80 +904,6 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
class VideoGLRendererPixelTest : public GLRendererPixelTest {
protected:
- void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState* shared_state,
- media::VideoFrame::Format format,
- bool is_transparent,
- const gfx::RectF& tex_coord_rect,
- RenderPass* render_pass) {
- const gfx::Rect rect(this->device_viewport_size_);
-
- scoped_refptr<media::VideoFrame> video_frame =
- media::VideoFrame::CreateFrame(
- format, rect.size(), rect, rect.size(), base::TimeDelta());
-
- // YUV values representing a striped pattern, for validating texture
- // coordinates for sampling.
- uint8_t y_value = 0;
- uint8_t u_value = 0;
- uint8_t v_value = 0;
- for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
- uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
- video_frame->stride(media::VideoFrame::kYPlane) * i;
- for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
- ++j) {
- y_row[j] = (y_value += 1);
- }
- }
- for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
- uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
- video_frame->stride(media::VideoFrame::kUPlane) * i;
- uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
- video_frame->stride(media::VideoFrame::kVPlane) * i;
- for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
- ++j) {
- u_row[j] = (u_value += 3);
- v_row[j] = (v_value += 5);
- }
- }
- uint8 alpha_value = is_transparent ? 0 : 128;
- CreateTestYUVVideoDrawQuad_FromVideoFrame(
- shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
- }
-
- void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state,
- media::VideoFrame::Format format,
- bool is_transparent,
- const gfx::RectF& tex_coord_rect,
- uint8 y,
- uint8 u,
- uint8 v,
- RenderPass* render_pass) {
- const gfx::Rect rect(this->device_viewport_size_);
-
- scoped_refptr<media::VideoFrame> video_frame =
- media::VideoFrame::CreateFrame(
- format, rect.size(), rect, rect.size(), base::TimeDelta());
-
- // YUV values of a solid, constant, color. Useful for testing that color
- // space/color range are being handled properly.
- memset(video_frame->data(media::VideoFrame::kYPlane),
- y,
- video_frame->stride(media::VideoFrame::kYPlane) *
- video_frame->rows(media::VideoFrame::kYPlane));
- memset(video_frame->data(media::VideoFrame::kUPlane),
- u,
- video_frame->stride(media::VideoFrame::kUPlane) *
- video_frame->rows(media::VideoFrame::kUPlane));
- memset(video_frame->data(media::VideoFrame::kVPlane),
- v,
- video_frame->stride(media::VideoFrame::kVPlane) *
- video_frame->rows(media::VideoFrame::kVPlane));
-
- uint8 alpha_value = is_transparent ? 0 : 128;
- CreateTestYUVVideoDrawQuad_FromVideoFrame(
- shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
- }
-
void CreateEdgeBleedPass(media::VideoFrame::Format format,
RenderPassList* pass_list) {
gfx::Rect rect(200, 200);
@@ -492,139 +932,19 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
// green sub-rectangle that should be the only thing displayed in
// the final image. Bleeding will appear on all four sides of the video
// if the tex coords are not clamped.
- CreateTestYUVVideoDrawQuad_TwoColor(shared_state, format, false,
- tex_coord_rect, background_size, 0, 0,
- 0, green_rect, 149, 43, 21, pass.get());
+ CreateTestYUVVideoDrawQuad_TwoColor(
+ shared_state, format, false, tex_coord_rect, background_size, 0, 0, 0,
+ green_rect, 149, 43, 21, pass.get(), video_resource_updater_.get(),
+ resource_provider_.get());
pass_list->push_back(pass.Pass());
}
- // Creates a video frame of size background_size filled with yuv_background,
- // and then draws a foreground rectangle in a different color on top of
- // that. The foreground rectangle must have coordinates that are divisible
- // by 2 because YUV is a block format.
- void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState* shared_state,
- media::VideoFrame::Format format,
- bool is_transparent,
- const gfx::RectF& tex_coord_rect,
- const gfx::Size& background_size,
- uint8 y_background,
- uint8 u_background,
- uint8 v_background,
- const gfx::Rect& foreground_rect,
- uint8 y_foreground,
- uint8 u_foreground,
- uint8 v_foreground,
- RenderPass* render_pass) {
- const gfx::Rect rect(background_size);
-
- scoped_refptr<media::VideoFrame> video_frame =
- media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
- foreground_rect.size(),
- base::TimeDelta());
-
- int planes[] = {media::VideoFrame::kYPlane,
- media::VideoFrame::kUPlane,
- media::VideoFrame::kVPlane};
- uint8 yuv_background[] = {y_background, u_background, v_background};
- uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
- int sample_size[] = {1, 2, 2};
-
- for (int i = 0; i < 3; ++i) {
- memset(video_frame->data(planes[i]), yuv_background[i],
- video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
- }
-
- for (int i = 0; i < 3; ++i) {
- // Since yuv encoding uses block encoding, widths have to be divisible
- // by the sample size in order for this function to behave properly.
- DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
- DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
- DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
- DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
-
- gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
- foreground_rect.y() / sample_size[i],
- foreground_rect.width() / sample_size[i],
- foreground_rect.height() / sample_size[i]);
- for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
- for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
- size_t offset = y * video_frame->stride(planes[i]) + x;
- video_frame->data(planes[i])[offset] = yuv_foreground[i];
- }
- }
- }
-
- uint8 alpha_value = 255;
- CreateTestYUVVideoDrawQuad_FromVideoFrame(
- shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
- }
-
- void CreateTestYUVVideoDrawQuad_FromVideoFrame(
- const SharedQuadState* shared_state,
- scoped_refptr<media::VideoFrame> video_frame,
- uint8 alpha_value,
- const gfx::RectF& tex_coord_rect,
- RenderPass* render_pass) {
- const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
- const YUVVideoDrawQuad::ColorSpace color_space =
- (video_frame->format() == media::VideoFrame::YV12J
- ? YUVVideoDrawQuad::JPEG
- : YUVVideoDrawQuad::REC_601);
- const gfx::Rect rect(shared_state->content_bounds);
- const gfx::Rect opaque_rect(0, 0, 0, 0);
-
- if (with_alpha)
- memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
- video_frame->stride(media::VideoFrame::kAPlane) *
- video_frame->rows(media::VideoFrame::kAPlane));
-
- VideoFrameExternalResources 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());
-
- ResourceProvider::ResourceId y_resource =
- resource_provider_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kYPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kYPlane]));
- ResourceProvider::ResourceId u_resource =
- resource_provider_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kUPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kUPlane]));
- ResourceProvider::ResourceId v_resource =
- resource_provider_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kVPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kVPlane]));
- ResourceProvider::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]));
- }
-
- YUVVideoDrawQuad* yuv_quad =
- render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
- yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
- video_frame->coded_size(), y_resource, u_resource,
- v_resource, a_resource, color_space);
- }
-
void SetUp() override {
GLRendererPixelTest::SetUp();
video_resource_updater_.reset(new VideoResourceUpdater(
output_surface_->context_provider(), resource_provider_.get()));
}
- private:
scoped_ptr<VideoResourceUpdater> video_resource_updater_;
};
@@ -637,11 +957,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
- CreateTestYUVVideoDrawQuad_Striped(shared_state,
- media::VideoFrame::YV12,
- false,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- pass.get());
+ CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12,
+ false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+ pass.get(), video_resource_updater_.get(),
+ rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -662,11 +981,10 @@ TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
// Intentionally sets frame format to I420 for testing coverage.
- CreateTestYUVVideoDrawQuad_Striped(shared_state,
- media::VideoFrame::I420,
- false,
- gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f),
- pass.get());
+ CreateTestYUVVideoDrawQuad_Striped(
+ shared_state, media::VideoFrame::I420, false,
+ gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
+ video_resource_updater_.get(), rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -687,14 +1005,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
// In MPEG color range YUV values of (15,128,128) should produce black.
- CreateTestYUVVideoDrawQuad_Solid(shared_state,
- media::VideoFrame::YV12,
- false,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- 15,
- 128,
- 128,
- pass.get());
+ CreateTestYUVVideoDrawQuad_Solid(
+ shared_state, media::VideoFrame::YV12, false,
+ gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
+ video_resource_updater_.get(), rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -716,14 +1030,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
// YUV of (149,43,21) should be green (0,255,0) in RGB.
- CreateTestYUVVideoDrawQuad_Solid(shared_state,
- media::VideoFrame::YV12J,
- false,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- 149,
- 43,
- 21,
- pass.get());
+ CreateTestYUVVideoDrawQuad_Solid(
+ shared_state, media::VideoFrame::YV12J, false,
+ gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
+ video_resource_updater_.get(), rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -761,14 +1071,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
// Dark grey in JPEG color range (in MPEG, this is black).
- CreateTestYUVVideoDrawQuad_Solid(shared_state,
- media::VideoFrame::YV12J,
- false,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- 15,
- 128,
- 128,
- pass.get());
+ CreateTestYUVVideoDrawQuad_Solid(
+ shared_state, media::VideoFrame::YV12J, false,
+ gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
+ video_resource_updater_.get(), rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -788,11 +1094,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
- CreateTestYUVVideoDrawQuad_Striped(shared_state,
- media::VideoFrame::YV12A,
- false,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- pass.get());
+ CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
+ false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+ pass.get(), video_resource_updater_.get(),
+ rect, resource_provider_.get());
SolidColorDrawQuad* color_quad =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -816,11 +1121,10 @@ TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
- CreateTestYUVVideoDrawQuad_Striped(shared_state,
- media::VideoFrame::YV12A,
- true,
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
- pass.get());
+ CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
+ true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+ pass.get(), video_resource_updater_.get(),
+ rect, resource_provider_.get());
SolidColorDrawQuad* color_quad =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();