Index: media/renderers/skcanvas_video_renderer_unittest.cc |
diff --git a/media/renderers/skcanvas_video_renderer_unittest.cc b/media/renderers/skcanvas_video_renderer_unittest.cc |
index 3fe348e99f282a7792b0ace1718e1f6479d3f056..e24f1f5bf6beb1ef7ed5e7faed207f4f2c753965 100644 |
--- a/media/renderers/skcanvas_video_renderer_unittest.cc |
+++ b/media/renderers/skcanvas_video_renderer_unittest.cc |
@@ -3,6 +3,7 @@ |
// found in the LICENSE file. |
#include <stdint.h> |
+#include <GLES3/gl3.h> |
#include "base/macros.h" |
#include "base/message_loop/message_loop.h" |
@@ -519,6 +520,10 @@ class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub { |
DCHECK_EQ(1, n); |
*textures = 1; |
} |
+ |
+ GLuint CreateProgram() override { return ++program_base_; } |
+ |
+ unsigned program_base_ = 0; |
}; |
void MailboxHoldersReleased(const gpu::SyncToken& sync_token) {} |
} // namespace |
@@ -590,4 +595,57 @@ TEST_F(SkCanvasVideoRendererTest, CorrectFrameSizeToVisibleRect) { |
EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().height()); |
} |
+// Test that cached resources are restored when gl context is lost and restored. |
+TEST_F(SkCanvasVideoRendererTest, Y16CachedGLResourcesContextRestore) { |
+ sk_sp<const GrGLInterface> null_interface(GrGLCreateNullInterface()); |
+ sk_sp<GrContext> gr_context(GrContext::Create( |
+ kOpenGL_GrBackend, |
+ reinterpret_cast<GrBackendContext>(null_interface.get()))); |
+ |
+ SkCanvas canvas(AllocBitmap(kWidth, kHeight)); |
+ |
+ TestGLES2Interface gles2; |
+ TestGLES2Interface gl_destination; |
+ unsigned texture, texture1, texture2; |
+ gl_destination.GenTextures(1, &texture); |
+ Context3D context_3d(&gles2, gr_context.get()); |
+ gfx::Size size(kWidth, kHeight); |
+ gpu::MailboxHolder holders[VideoFrame::kMaxPlanes] = {gpu::MailboxHolder( |
+ gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D)}; |
+ auto video_frame = VideoFrame::WrapNativeTextures( |
+ PIXEL_FORMAT_Y16, holders, base::Bind(MailboxHoldersReleased), size, |
+ gfx::Rect(size), size, kNoTimestamp); |
+ |
+ unsigned program_base_before = gles2.program_base_; |
+ renderer_.CopyVideoFrameTexturesToGLTexture( |
+ context_3d, &gl_destination, video_frame.get(), texture, GL_R32F, |
+ GL_FLOAT, true /*premultiply_alpha*/, true /*flip_y*/); |
+ // It is expected that the program for RG8 -> R32F conversion is created. |
+ EXPECT_EQ(gles2.program_base_ - program_base_before, 1u); |
+ |
+ gl_destination.GenTextures(1, &texture1); |
+ program_base_before = gles2.program_base_; |
+ renderer_.CopyVideoFrameTexturesToGLTexture( |
+ context_3d, &gl_destination, video_frame.get(), texture, GL_R32F, |
+ GL_FLOAT, true /*premultiply_alpha*/, true /*flip_y*/); |
+ // The program is expected to be cached - no new program created. |
+ EXPECT_EQ(gles2.program_base_ - program_base_before, 0u); |
+ |
+ gr_context->abandonContext(); |
+ |
+ sk_sp<const GrGLInterface> null_interface_1(GrGLCreateNullInterface()); |
+ sk_sp<GrContext> gr_context_1(GrContext::Create( |
+ kOpenGL_GrBackend, |
+ reinterpret_cast<GrBackendContext>(null_interface_1.get()))); |
+ |
+ gl_destination.GenTextures(1, &texture2); |
+ Context3D context_3d_1(&gles2, gr_context_1.get()); |
+ program_base_before = gles2.program_base_; |
+ renderer_.CopyVideoFrameTexturesToGLTexture( |
+ context_3d_1, &gl_destination, video_frame.get(), texture1, GL_R32F, |
+ GL_FLOAT, true /*premultiply_alpha*/, true /*flip_y*/); |
+ // As the new context is created, the new program is expected. |
+ EXPECT_EQ(gles2.program_base_ - program_base_before, 1u); |
+} |
+ |
} // namespace media |