Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2456213002: WebVR: implement SetSurfaceHandleCHROMIUM extension for gvr_device.
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698