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

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

Issue 2456213002: WebVR: implement SetSurfaceHandleCHROMIUM extension for gvr_device.
Patch Set: bajones #16, #19: Use struct for state, fix BUILD deps Created 4 years, 1 month 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 c480b71567dca3814c19aeca0b4f7185bc338e42..eeee706c51c834c111fed9093c0c1f7f88314883 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"
piman 2016/11/09 17:50:07 So, including gpu/ipc is a layering violation. Ind
klausw 2016/11/11 00:04:10 I'm a bit confused about the layering violation an
#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"
piman 2016/11/09 17:50:06 I believe we can't include this on Mac (EGL is not
klausw 2016/11/09 21:21:55 Done, now Android only.
#include "ui/gl/gl_version_info.h"
#include "ui/gl/gpu_timing.h"
@@ -1034,6 +1036,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);
@@ -2131,6 +2135,17 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
scoped_refptr<gl::GLSurface> surface_;
scoped_refptr<gl::GLContext> context_;
+ // Direct render mode data for switching and restoring the
+ // underlying destination surface, cf. DoSetSurfaceHandleCHROMIUM.
+ struct DirectRenderState{
+ scoped_refptr<gl::GLSurface> direct_surface;
+ scoped_refptr<gl::GLSurface> orig_surface;
+ std::unique_ptr<BackFramebuffer> orig_offscreen_target_frame_buffer;
+ bool orig_supports_async_swap;
+ bool orig_back_buffer_has_depth;
piman 2016/11/09 17:50:07 saving/restoring the old values seems like additio
klausw 2016/11/09 21:21:56 I've refactored it by extracting bits of Initializ
+ };
+ std::unique_ptr<DirectRenderState> direct_render_state_;
+
// The ContextGroup for this decoder uses to track resources.
scoped_refptr<ContextGroup> group_;
@@ -16937,6 +16952,85 @@ void GLES2DecoderImpl::DoApplyScreenSpaceAntialiasingCHROMIUM() {
}
}
+void GLES2DecoderImpl::DoSetSurfaceHandleCHROMIUM(GLint surface_handle) {
+#if defined(OS_ANDROID)
+ if (surface_handle) {
+ // Use the specified surface as a render target, and save decoder
+ // state so that this can be reverted 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.
piman 2016/11/09 17:50:06 This is a bit distasteful as an API... It doesn't
klausw 2016/11/09 21:21:55 Fixed, it raises an error now if the current conte
+ if (direct_render_state_) {
+ return;
+ }
+
+ direct_render_state_.reset(new DirectRenderState());
+
+ // One-time initialization when first activating a direct draw surface.
+ ANativeWindow* window =
+ gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
+ surface_handle);
piman 2016/11/09 17:50:06 This could be NULL? How should we handle this?
klausw 2016/11/09 21:21:55 Changed to raise an error.
+ direct_render_state_->direct_surface =
+ new gl::NativeViewGLSurfaceEGL(window);
piman 2016/11/09 17:50:07 So, this is an extremely powerful capability. If t
klausw 2016/11/11 00:04:10 After discussion with Brandon, it sounds best to g
+
+ // It would be useful if we could get a custom surface format such
+ // as one with a depth buffer here, but the new surface must use
+ // the same format as the one originally used for creating the GL
+ // context. Anything else just results in BAD_MATCH errors.
+ bool initialize_success = direct_render_state_->direct_surface->Initialize(
+ surface_->GetFormat());
+ if (!initialize_success) {
+ LOG(ERROR) << "Direct render surface init failed for handle " <<
+ surface_handle;
+ }
+ ANativeWindow_release(window);
+
+ direct_render_state_->orig_surface = surface_;
+
+ // We don't want async swap since we want full control over when the
+ // SurfaceTexture gets updated.
piman 2016/11/09 17:50:06 FYI, "async" swap doesn't remove any "control", it
klausw 2016/11/09 21:21:55 I removed this, I had misunderstood how it works a
+ direct_render_state_->orig_supports_async_swap = supports_async_swap_;
+ supports_async_swap_ = false;
piman 2016/11/09 17:50:06 what about other properties of the surface, like s
klausw 2016/11/09 21:21:55 See above, the new shared methods should keep them
+ direct_render_state_->orig_back_buffer_has_depth = back_buffer_has_depth_;
+ back_buffer_has_depth_ = true;
piman 2016/11/09 17:50:06 What makes this true?
klausw 2016/11/09 21:21:55 This was an assumption based on the current use ca
+ // override back_buffer_has_stencil_ too?
piman 2016/11/09 17:50:07 What is this comment, is it a TODO? If so, please
klausw 2016/11/09 21:21:55 Should be fixed now.
+
+ // 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().
+ direct_render_state_->orig_offscreen_target_frame_buffer =
+ std::move(offscreen_target_frame_buffer_);
+ offscreen_target_frame_buffer_.reset(nullptr);
+
+ // Activate the surface. This does *not* rebind the active framebuffer,
+ // callers must do so themselves as needed.
piman 2016/11/09 17:50:06 We should keep a consistent state. If the default
klausw 2016/11/09 21:21:55 I've added MakeCurrent and am applying glViewport
piman 2016/11/09 22:26:09 Correct.
klausw 2016/11/10 02:28:07 Acknowledged.
+ SetSurface(direct_render_state_->direct_surface);
+ } else {
+ // Restore original state for drawing offscreen.
+
+ // Ignore redundant calls.
+ if (!direct_render_state_) return;
+
+ supports_async_swap_ = direct_render_state_->orig_supports_async_swap;
+ back_buffer_has_depth_ = direct_render_state_->orig_back_buffer_has_depth;
+ offscreen_target_frame_buffer_ =
+ std::move(direct_render_state_->orig_offscreen_target_frame_buffer);
+
+ SetSurface(direct_render_state_->orig_surface);
+
+ // Trust the state struct's destructors to handle refcounting for
+ // surfaces and trigger apprpriate cleanup.
+ direct_render_state_.reset();
+ }
+#else // !OS_ANDROID
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION,
+ "glSetSurfaceHandleCHROMIUM",
+ "Direct render surface is unsupported on this platform");
+#endif
+}
+
void GLES2DecoderImpl::DoInsertEventMarkerEXT(
GLsizei length, const GLchar* marker) {
if (!marker) {

Powered by Google App Engine
This is Rietveld 408576698