Index: android_webview/browser/in_process_renderer/in_process_view_renderer.cc |
diff --git a/android_webview/browser/in_process_renderer/in_process_view_renderer.cc b/android_webview/browser/in_process_renderer/in_process_view_renderer.cc |
index e0b9e8f63b30803e4a29d42d8eae189306ffe7dc..6ecdd6215e5e3cae02d437723a1a970f04860cdd 100644 |
--- a/android_webview/browser/in_process_renderer/in_process_view_renderer.cc |
+++ b/android_webview/browser/in_process_renderer/in_process_view_renderer.cc |
@@ -25,6 +25,17 @@ |
#include "ui/gfx/vector2d_f.h" |
#include "ui/gl/gl_bindings.h" |
+// TODO(leandrogracia): Borrowed from gl2ext.h. Cannot be included due to |
+// conflicts with gl_bindings.h and the EGL library methods |
+// (eglGetCurrentContext). |
+#ifndef GL_TEXTURE_EXTERNAL_OES |
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65 |
+#endif |
+ |
+#ifndef GL_TEXTURE_BINDING_EXTERNAL_OES |
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 |
+#endif |
+ |
using base::android::AttachCurrentThread; |
using base::android::JavaRef; |
using base::android::ScopedJavaLocalRef; |
@@ -34,6 +45,142 @@ using content::ContentViewCore; |
namespace android_webview { |
namespace { |
+ |
+class GLStateRestore { |
+ public: |
+ GLStateRestore() { |
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, |
+ &texture_external_oes_binding_); |
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); |
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, |
+ &index_array_buffer_binding_); |
+ glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_); |
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_); |
+ |
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
+ glGetVertexAttribiv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled); |
+ glGetVertexAttribiv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size); |
+ glGetVertexAttribiv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type); |
+ glGetVertexAttribiv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized); |
+ glGetVertexAttribiv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride); |
+ glGetVertexAttribPointerv( |
+ i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); |
+ } |
+ |
+ glGetBooleanv(GL_DEPTH_TEST, &depth_test_); |
+ glGetBooleanv(GL_CULL_FACE, &cull_face_); |
+ glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_); |
+ glGetBooleanv(GL_BLEND, &blend_enabled_); |
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); |
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); |
+ glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); |
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); |
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_); |
+ glGetIntegerv(GL_VIEWPORT, viewport_); |
+ glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); |
+ glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); |
+ glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_); |
+ |
+ DCHECK_EQ(0, vertex_array_buffer_binding_); |
+ DCHECK_EQ(0, index_array_buffer_binding_); |
+ } |
+ |
+ ~GLStateRestore() { |
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding_); |
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); |
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); |
+ glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_); |
+ glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_); |
+ |
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
+ glVertexAttribPointer(i, |
+ vertex_attrib_[i].size, |
+ vertex_attrib_[i].type, |
+ vertex_attrib_[i].normalized, |
+ vertex_attrib_[i].stride, |
+ vertex_attrib_[i].pointer); |
+ |
+ if (vertex_attrib_[i].enabled) { |
+ glEnableVertexAttribArray(i); |
+ } else { |
+ glDisableVertexAttribArray(i); |
+ } |
+ } |
+ |
+ if (depth_test_) { |
+ glEnable(GL_DEPTH_TEST); |
+ } else { |
+ glDisable(GL_DEPTH_TEST); |
+ } |
+ |
+ if (cull_face_) { |
+ glEnable(GL_CULL_FACE); |
+ } else { |
+ glDisable(GL_CULL_FACE); |
+ } |
+ |
+ glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]); |
+ |
+ if (blend_enabled_) { |
+ glEnable(GL_BLEND); |
+ } else { |
+ glDisable(GL_BLEND); |
+ } |
+ |
+ glBlendFuncSeparate( |
+ blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); |
+ glActiveTexture(active_texture_); |
+ |
+ glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); |
+ |
+ if (scissor_test_) { |
+ glEnable(GL_SCISSOR_TEST); |
+ } else { |
+ glDisable(GL_SCISSOR_TEST); |
+ } |
+ |
+ glScissor( |
+ scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); |
+ |
+ glUseProgram(current_program_); |
+ } |
+ |
+ private: |
+ GLint texture_external_oes_binding_; |
+ GLint vertex_array_buffer_binding_; |
+ GLint index_array_buffer_binding_; |
+ GLint pack_alignment_; |
+ GLint unpack_alignment_; |
+ |
+ struct { |
+ GLint enabled; |
+ GLint size; |
+ GLint type; |
+ GLint normalized; |
+ GLint stride; |
+ GLvoid* pointer; |
+ } vertex_attrib_[3]; |
+ |
+ GLboolean depth_test_; |
+ GLboolean cull_face_; |
+ GLboolean color_mask_[4]; |
+ GLboolean blend_enabled_; |
+ GLint blend_src_rgb_; |
+ GLint blend_src_alpha_; |
+ GLint blend_dest_rgb_; |
+ GLint blend_dest_alpha_; |
+ GLint active_texture_; |
+ GLint viewport_[4]; |
+ GLboolean scissor_test_; |
+ GLint scissor_box_[4]; |
+ GLint current_program_; |
+}; |
+ |
const void* kUserDataKey = &kUserDataKey; |
class UserData : public content::WebContents::Data { |
@@ -198,6 +345,8 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
return; |
} |
+ GLStateRestore state_restore; |
+ |
if (attached_to_window_ && compositor_ && !hardware_initialized_) { |
// TODO(boliu): Actually initialize the compositor GL path. |
hardware_initialized_ = true; |
@@ -228,11 +377,6 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
draw_info->clip_right - draw_info->clip_left, |
draw_info->clip_bottom - draw_info->clip_top)); |
- // The GL functor must ensure these are set to zero before returning. |
- // Not setting them leads to graphical artifacts that can affect other apps. |
- glBindBuffer(GL_ARRAY_BUFFER, 0); |
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
- |
EnsureContinuousInvalidation(); |
} |