Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index f89fe640783f6e82b319c51b716c6b9b6ca8b346..5c1da7b1ba8cbc2d635c6c2777a3b402af2c8419 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -65,6 +65,7 @@ |
| #include "gpu/command_buffer/service/transform_feedback_manager.h" |
| #include "gpu/command_buffer/service/vertex_array_manager.h" |
| #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
| +#include "gpu/ipc/common/gpu_surface_lookup.h" |
| #include "third_party/angle/src/image_util/loadimage.h" |
| #include "third_party/smhasher/src/City.h" |
| #include "ui/gfx/buffer_types.h" |
| @@ -82,6 +83,7 @@ |
| #include "ui/gl/gl_image.h" |
| #include "ui/gl/gl_implementation.h" |
| #include "ui/gl/gl_surface.h" |
| +#include "ui/gl/gl_surface_egl.h" |
| #include "ui/gl/gl_version_info.h" |
| #include "ui/gl/gpu_timing.h" |
| @@ -1056,6 +1058,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| void DoFlushMappedBufferRange( |
| GLenum target, GLintptr offset, GLsizeiptr size); |
| + void DoSetSurfaceHandleCHROMIUM(GLint surface_handle); |
| + |
| // Creates a Program for the given program. |
| Program* CreateProgram(GLuint client_id, GLuint service_id) { |
| return program_manager()->CreateProgram(client_id, service_id); |
| @@ -2153,6 +2157,12 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| scoped_refptr<gl::GLSurface> surface_; |
| scoped_refptr<gl::GLContext> context_; |
| + // WebVR data for switching and restoring the underlying destination surface. |
| + scoped_refptr<gl::GLSurface> webvr_surface_; |
| + scoped_refptr<gl::GLSurface> webvr_orig_surface_; |
| + std::unique_ptr<BackFramebuffer> webvr_orig_offscreen_target_frame_buffer_; |
| + bool webvr_orig_supports_async_swap_; |
| + |
| // The ContextGroup for this decoder uses to track resources. |
| scoped_refptr<ContextGroup> group_; |
| @@ -16807,6 +16817,72 @@ void GLES2DecoderImpl::DoApplyScreenSpaceAntialiasingCHROMIUM() { |
| } |
| } |
| +void GLES2DecoderImpl::DoSetSurfaceHandleCHROMIUM(GLint surface_handle) { |
|
bajones
2016/10/28 00:41:22
Looking at this implementation the function name i
bajones
2016/10/28 16:47:46
Oh, and I also realized last night that you're goi
klausw
2016/11/08 02:18:30
It no longer changes the framebuffer binding in th
klausw
2016/11/08 02:18:30
Done, and added an #else to raise a GL_INVALID_OPE
|
| + if (surface_handle) { |
| + // Use the specified surface as a render target, saving the offscreen |
| + // render buffer so that we can restore it later. |
| + |
| + // Ignore redundant calls. For now we don't support switching between |
| + // different surfaces, if you need this you have to make a call with |
| + // surface_handle=0 in between. |
| + if (webvr_surface_) return; |
| + |
| + // One-time initialization when first activating WebVR surface. |
| + ANativeWindow* window = |
| + gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( |
| + surface_handle); |
| + webvr_surface_ = new gl::NativeViewGLSurfaceEGL(window); |
| + // TODO(klausw): need to add a depth buffer for doing 3D rendering. |
| + // Currently it's just used for a 2D copy. |
| + bool initialize_success = |
| + webvr_surface_->Initialize(gl::GLSurface::SURFACE_ARGB8888); |
| + if (!initialize_success) { |
| + LOG(ERROR) << "WebVR surface init failed, handle=" << surface_handle; |
| + } |
| + ANativeWindow_release(window); |
| + |
| + webvr_orig_surface_ = surface_; |
| + |
| + // We don't want async swap since we want full control over when the |
| + // SurfaceTexture gets updated. |
| + webvr_orig_supports_async_swap_ = supports_async_swap_; |
| + supports_async_swap_ = false; |
| + |
| + // Offscreen surfaces don't support SwapBuffers, make sure it's not |
| + // considered offscreen. Various code in this file checks for is_offscreen |
| + // = !!offscreen_target_frame_buffer_.get(). |
| + webvr_orig_offscreen_target_frame_buffer_ = |
| + std::move(offscreen_target_frame_buffer_); |
| + offscreen_target_frame_buffer_.reset(nullptr); |
| + |
| + // Activate the surface, and use it for rendering. |
| + SetSurface(webvr_surface_); |
| + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); |
| + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); |
| + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); |
| + |
| + // TODO(klausw): is any additional cleanup needed in destructor, or |
| + // do smart pointers do the right thing already? |
| + } else { |
| + // Restore original state for drawing offscreen. |
| + |
| + // Ignore redundant calls. |
| + if (!webvr_surface_) return; |
| + |
| + // TODO(klausw): check if this is sufficient cleanup, I'm assuming that |
| + // clearing the smart pointer calls the appropriate destructor. |
| + webvr_surface_ = nullptr; |
| + |
| + supports_async_swap_ = webvr_orig_supports_async_swap_; |
| + |
| + offscreen_target_frame_buffer_ = |
| + std::move(webvr_orig_offscreen_target_frame_buffer_); |
| + webvr_orig_offscreen_target_frame_buffer_.reset(nullptr); |
| + |
| + SetSurface(webvr_orig_surface_); |
| + } |
| +} |
| + |
| void GLES2DecoderImpl::DoInsertEventMarkerEXT( |
| GLsizei length, const GLchar* marker) { |
| if (!marker) { |