Commit 729d1b4a authored by robert.bradford's avatar robert.bradford Committed by Commit bot

Use GLHelper for glReadPixels and format detection

GLHelper has functionality for testing for appropriate GL readback
format support, caching this information where appropriate. This change
switches RendererGpuVideoAcceleratorFactories over to using that code
for supported format identification and glReadPixels in the desired
format. The code continues to do a software swizzle if necessary.

TEST=WebGL conformance tests
BUG=None

Review URL: https://codereview.chromium.org/456823002

Cr-Commit-Position: refs/heads/master@{#293358}
parent a9900086
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "content/child/child_thread.h" #include "content/child/child_thread.h"
#include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
...@@ -64,11 +65,24 @@ RendererGpuVideoAcceleratorFactories::GetContext3d() { ...@@ -64,11 +65,24 @@ RendererGpuVideoAcceleratorFactories::GetContext3d() {
if (context_provider_->IsContextLost()) { if (context_provider_->IsContextLost()) {
context_provider_->VerifyContexts(); context_provider_->VerifyContexts();
context_provider_ = NULL; context_provider_ = NULL;
gl_helper_.reset(NULL);
return NULL; return NULL;
} }
return context_provider_->WebContext3D(); return context_provider_->WebContext3D();
} }
GLHelper* RendererGpuVideoAcceleratorFactories::GetGLHelper() {
if (!GetContext3d())
return NULL;
if (gl_helper_.get() == NULL) {
gl_helper_.reset(new GLHelper(GetContext3d()->GetImplementation(),
GetContext3d()->GetContextSupport()));
}
return gl_helper_.get();
}
scoped_ptr<media::VideoDecodeAccelerator> scoped_ptr<media::VideoDecodeAccelerator>
RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() { RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
...@@ -178,59 +192,29 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels( ...@@ -178,59 +192,29 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(
const SkBitmap& pixels) { const SkBitmap& pixels) {
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
GLHelper* gl_helper = GetGLHelper();
WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
if (!context)
return;
gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); if (!gl_helper || !context)
return;
// Copy texture from texture_id to tmp_texture as texture might be external
// (GL_TEXTURE_EXTERNAL_OES)
GLuint tmp_texture; GLuint tmp_texture;
gles2->GenTextures(1, &tmp_texture); tmp_texture = gl_helper->CreateTexture();
gles2->BindTexture(GL_TEXTURE_2D, tmp_texture);
gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
context->copyTextureCHROMIUM( context->copyTextureCHROMIUM(
GL_TEXTURE_2D, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE); GL_TEXTURE_2D, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE);
GLuint fb; unsigned char* pixel_data =
gles2->GenFramebuffers(1, &fb); static_cast<unsigned char*>(pixels.pixelRef()->pixels());
gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
gles2->FramebufferTexture2D( if (gl_helper->IsReadbackConfigSupported(pixels.colorType())) {
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0); gl_helper->ReadbackTextureSync(
gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); tmp_texture, visible_rect, pixel_data, pixels.colorType());
} else if (pixels.colorType() == kN32_SkColorType) {
#if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ gl_helper->ReadbackTextureSync(
SK_A32_SHIFT == 24 tmp_texture, visible_rect, pixel_data, kRGBA_8888_SkColorType);
GLenum skia_format = GL_BGRA_EXT;
GLenum read_format = GL_BGRA_EXT;
GLint supported_format = 0;
GLint supported_type = 0;
gles2->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &supported_format);
gles2->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &supported_type);
if (supported_format != GL_BGRA_EXT || supported_type != GL_UNSIGNED_BYTE) {
read_format = GL_RGBA;
}
#elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
SK_A32_SHIFT == 24
GLenum skia_format = GL_RGBA;
GLenum read_format = GL_RGBA;
#else
#error Unexpected Skia ARGB_8888 layout!
#endif
gles2->ReadPixels(visible_rect.x(),
visible_rect.y(),
visible_rect.width(),
visible_rect.height(),
read_format,
GL_UNSIGNED_BYTE,
pixels.pixelRef()->pixels());
gles2->DeleteFramebuffers(1, &fb);
gles2->DeleteTextures(1, &tmp_texture);
if (skia_format != read_format) {
DCHECK(read_format == GL_RGBA);
int pixel_count = visible_rect.width() * visible_rect.height(); int pixel_count = visible_rect.width() * visible_rect.height();
uint32_t* pixels_ptr = static_cast<uint32_t*>(pixels.pixelRef()->pixels()); uint32_t* pixels_ptr = static_cast<uint32_t*>(pixels.pixelRef()->pixels());
for (int i = 0; i < pixel_count; ++i) { for (int i = 0; i < pixel_count; ++i) {
...@@ -243,9 +227,11 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels( ...@@ -243,9 +227,11 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(
(b << SK_B32_SHIFT) | (b << SK_B32_SHIFT) |
(a << SK_A32_SHIFT); (a << SK_A32_SHIFT);
} }
} else {
NOTREACHED();
} }
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); gl_helper->DeleteTexture(tmp_texture);
} }
base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory(
......
...@@ -22,6 +22,7 @@ class WaitableEvent; ...@@ -22,6 +22,7 @@ class WaitableEvent;
namespace content { namespace content {
class ContextProviderCommandBuffer; class ContextProviderCommandBuffer;
class GLHelper;
class GpuChannelHost; class GpuChannelHost;
class WebGraphicsContext3DCommandBufferImpl; class WebGraphicsContext3DCommandBufferImpl;
...@@ -78,10 +79,12 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories ...@@ -78,10 +79,12 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories
// Helper to get a pointer to the WebGraphicsContext3DCommandBufferImpl, // Helper to get a pointer to the WebGraphicsContext3DCommandBufferImpl,
// if it has not been lost yet. // if it has not been lost yet.
WebGraphicsContext3DCommandBufferImpl* GetContext3d(); WebGraphicsContext3DCommandBufferImpl* GetContext3d();
GLHelper* GetGLHelper();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<GpuChannelHost> gpu_channel_host_; scoped_refptr<GpuChannelHost> gpu_channel_host_;
scoped_refptr<ContextProviderCommandBuffer> context_provider_; scoped_refptr<ContextProviderCommandBuffer> context_provider_;
scoped_ptr<GLHelper> gl_helper_;
// For sending requests to allocate shared memory in the Browser process. // For sending requests to allocate shared memory in the Browser process.
scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<ThreadSafeSender> thread_safe_sender_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment