[go: up one dir, main page]

cmaa : Flip internally allocated framebuffer

MESA_framebuffer_flip_y needs the allocated framebuffer
to be setup to the same orientation.

BUG=964010
TEST=https://www.khronos.org/registry/webgl/sdk/tests/conformance/context/context-size-change.html?webglVersion=2

(cherry picked from commit e78b3019120dd19bcff7d853e89976e9be343146)

Change-Id: If7b7aaec176387e47c46c4f7337d686536375e8e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1641666
Reviewed-by: Antoine Labour <piman@chromium.org>
Commit-Queue: Fritz Koenig <frkoenig@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#666113}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1660785
Cr-Commit-Position: refs/branch-heads/3809@{#327}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 03cf41b..30a62773a 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -386,7 +386,8 @@
       draw_buffer_bound_mask_(0u),
       adjusted_draw_buffer_bound_mask_(0u),
       last_color_attachment_id_(-1),
-      read_buffer_(GL_COLOR_ATTACHMENT0) {
+      read_buffer_(GL_COLOR_ATTACHMENT0),
+      flip_y_(false) {
   manager->StartTracking(this);
   DCHECK_GT(manager->max_draw_buffers_, 0u);
   draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]);
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index 794df67..1670640 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -236,6 +236,9 @@
 
   void UnmarkAsComplete() { framebuffer_complete_state_count_id_ = 0; }
 
+  bool GetFlipY() const { return flip_y_; }
+  void SetFlipY(bool flip_y) { flip_y_ = flip_y; }
+
  private:
   friend class FramebufferManager;
   friend class base::RefCounted<Framebuffer>;
@@ -315,6 +318,8 @@
 
   GLenum read_buffer_;
 
+  bool flip_y_;
+
   DISALLOW_COPY_AND_ASSIGN(Framebuffer);
 };
 
diff --git a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
index cceecc6..d549220 100644
--- a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
+++ b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
@@ -26,6 +26,7 @@
       supports_usampler_(true),
       supports_r8_image_(true),
       is_gles31_compatible_(false),
+      flip_y_(false),
       frame_id_(0),
       width_(0),
       height_(0),
@@ -226,7 +227,7 @@
       GLenum internal_format = attachment->internal_format();
 
       // Resize internal structures - only if needed.
-      OnSize(width, height);
+      OnSize(width, height, framebuffer->GetFlipY());
 
       // CMAA internally expects GL_RGBA8 textures.
       // Process using a GL_RGBA8 copy if this is not the case.
@@ -500,14 +501,16 @@
 }
 
 void ApplyFramebufferAttachmentCMAAINTELResourceManager::OnSize(GLint width,
-                                                                GLint height) {
-  if (height_ == height && width_ == width)
+                                                                GLint height,
+                                                                bool flip_y) {
+  if (height_ == height && width_ == width && flip_y_ == flip_y)
     return;
 
   ReleaseTextures();
 
   height_ = height;
   width_ = width;
+  flip_y_ = flip_y;
 
   glGenTextures(1, &rgba8_texture_);
   glBindTexture(GL_TEXTURE_2D, rgba8_texture_);
@@ -549,6 +552,10 @@
   // Create the FBO
   glGenFramebuffersEXT(1, &cmaa_framebuffer_);
   glBindFramebufferEXT(GL_FRAMEBUFFER, cmaa_framebuffer_);
+  if (flip_y_) {
+    glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
+                            GL_TRUE);
+  }
 
   // We need to clear the textures before they are first used.
   // The algorithm self-clears them later.
diff --git a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.h b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.h
index 33bade3..11ded04 100644
--- a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.h
+++ b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.h
@@ -44,7 +44,7 @@
                               GLuint dest_texture,
                               bool do_copy);
 
-  void OnSize(GLint width, GLint height);
+  void OnSize(GLint width, GLint height, bool flip_y);
   void ReleaseTextures();
 
   GLuint CreateProgram(const char* defines,
@@ -58,6 +58,7 @@
   bool supports_usampler_;
   bool supports_r8_image_;
   bool is_gles31_compatible_;
+  bool flip_y_;
 
   int frame_id_;
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index bc72d26..9d5d01c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8259,12 +8259,19 @@
                                                GLenum pname,
                                                GLint param) {
   const char* func_name = "glFramebufferParameteri";
+  DCHECK(pname == GL_FRAMEBUFFER_FLIP_Y_MESA);
   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
   if (!framebuffer) {
     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no framebuffer bound");
     return;
   }
+  if (param != GL_TRUE && param != GL_FALSE) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
+                       "invalid parameter, only GL_TRUE or GL_FALSE accepted");
+    return;
+  }
   api()->glFramebufferParameteriFn(target, pname, param);
+  framebuffer->SetFlipY(param == GL_TRUE);
 }
 
 void GLES2DecoderImpl::DoFramebufferRenderbuffer(