Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / client / gles2_implementation.cc
index 78eccf5..9275a49 100644 (file)
@@ -11,8 +11,8 @@
 #include <queue>
 #include <set>
 #include <limits>
-#include <stdio.h>
-#include <string.h>
+#include <sstream>
+#include <string>
 #include <GLES2/gl2ext.h>
 #include <GLES2/gl2extchromium.h>
 #include "gpu/command_buffer/client/buffer_tracker.h"
@@ -72,13 +72,13 @@ GLES2Implementation::GLStaticState::IntState::IntState()
 GLES2Implementation::SingleThreadChecker::SingleThreadChecker(
     GLES2Implementation* gles2_implementation)
     : gles2_implementation_(gles2_implementation) {
-  GPU_CHECK_EQ(0, gles2_implementation_->use_count_);
+  CHECK_EQ(0, gles2_implementation_->use_count_);
   ++gles2_implementation_->use_count_;
 }
 
 GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() {
   --gles2_implementation_->use_count_;
-  GPU_CHECK_EQ(0, gles2_implementation_->use_count_);
+  CHECK_EQ(0, gles2_implementation_->use_count_);
 }
 
 GLES2Implementation::GLES2Implementation(
@@ -86,6 +86,7 @@ GLES2Implementation::GLES2Implementation(
       ShareGroup* share_group,
       TransferBufferInterface* transfer_buffer,
       bool bind_generates_resource,
+      bool free_everything_when_invisible,
       GpuControl* gpu_control)
     : helper_(helper),
       transfer_buffer_(transfer_buffer),
@@ -109,17 +110,19 @@ GLES2Implementation::GLES2Implementation(
       error_bits_(0),
       debug_(false),
       use_count_(0),
-      current_query_(NULL),
       error_message_callback_(NULL),
       gpu_control_(gpu_control),
+      surface_visible_(true),
+      free_everything_when_invisible_(free_everything_when_invisible),
+      capabilities_(gpu_control->GetCapabilities()),
       weak_ptr_factory_(this) {
-  GPU_DCHECK(helper);
-  GPU_DCHECK(transfer_buffer);
-  GPU_DCHECK(gpu_control);
+  DCHECK(helper);
+  DCHECK(transfer_buffer);
+  DCHECK(gpu_control);
 
-  char temp[128];
-  sprintf(temp, "%p", static_cast<void*>(this));
-  this_in_hex_ = std::string(temp);
+  std::stringstream ss;
+  ss << std::hex << this;
+  this_in_hex_ = ss.str();
 
   GPU_CLIENT_LOG_CODE_BLOCK({
     debug_ = CommandLine::ForCurrentProcess()->HasSwitch(
@@ -137,9 +140,9 @@ bool GLES2Implementation::Initialize(
     unsigned int min_transfer_buffer_size,
     unsigned int max_transfer_buffer_size,
     unsigned int mapped_memory_limit) {
-  GPU_DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size);
-  GPU_DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size);
-  GPU_DCHECK_GE(min_transfer_buffer_size, kStartingOffset);
+  DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size);
+  DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size);
+  DCHECK_GE(min_transfer_buffer_size, kStartingOffset);
 
   if (!transfer_buffer_->Initialize(
       starting_transfer_buffer_size,
@@ -336,6 +339,15 @@ void GLES2Implementation::SignalQuery(uint32 query,
                  callback));
 }
 
+void GLES2Implementation::SetSurfaceVisible(bool visible) {
+  // TODO(piman): This probably should be ShallowFlushCHROMIUM().
+  Flush();
+  surface_visible_ = visible;
+  gpu_control_->SetSurfaceVisible(visible);
+  if (!visible)
+    FreeEverything();
+}
+
 void GLES2Implementation::SendManagedMemoryStats(
     const ManagedMemoryStats& stats) {
   gpu_control_->SendManagedMemoryStats(stats);
@@ -447,7 +459,7 @@ GLenum GLES2Implementation::GetGLError() {
 #if defined(GL_CLIENT_FAIL_GL_ERRORS)
 void GLES2Implementation::FailGLError(GLenum error) {
   if (error != GL_NO_ERROR) {
-    GPU_NOTREACHED() << "Error";
+    NOTREACHED() << "Error";
   }
 }
 // NOTE: Calling GetGLError overwrites data in the result buffer.
@@ -483,7 +495,7 @@ void GLES2Implementation::SetGLErrorInvalidEnum(
 bool GLES2Implementation::GetBucketContents(uint32 bucket_id,
                                             std::vector<int8>* data) {
   TRACE_EVENT0("gpu", "GLES2::GetBucketContents");
-  GPU_DCHECK(data);
+  DCHECK(data);
   const uint32 kStartSize = 32 * 1024;
   ScopedTransferBufferPtr buffer(kStartSize, helper_, transfer_buffer_);
   if (!buffer.valid()) {
@@ -529,7 +541,7 @@ bool GLES2Implementation::GetBucketContents(uint32 bucket_id,
 
 void GLES2Implementation::SetBucketContents(
     uint32 bucket_id, const void* data, size_t size) {
-  GPU_DCHECK(data);
+  DCHECK(data);
   helper_->SetBucketSize(bucket_id, size);
   if (size > 0u) {
     uint32 offset = 0;
@@ -561,7 +573,7 @@ void GLES2Implementation::SetBucketAsCString(
 
 bool GLES2Implementation::GetBucketAsString(
     uint32 bucket_id, std::string* str) {
-  GPU_DCHECK(str);
+  DCHECK(str);
   std::vector<int8> data;
   // NOTE: strings are passed NULL terminated. That means the empty
   // string will have a size of 1 and no-string will have a size of 0
@@ -834,6 +846,8 @@ void GLES2Implementation::Flush() {
   // Flush our command buffer
   // (tell the service to execute up to the flush cmd.)
   helper_->CommandBufferHelper::Flush();
+  if (!surface_visible_ && free_everything_when_invisible_)
+    FreeEverything();
 }
 
 void GLES2Implementation::ShallowFlushCHROMIUM() {
@@ -842,15 +856,19 @@ void GLES2Implementation::ShallowFlushCHROMIUM() {
   // Flush our command buffer
   // (tell the service to execute up to the flush cmd.)
   helper_->CommandBufferHelper::Flush();
+  // TODO(piman): Add the FreeEverything() logic here.
 }
 
 void GLES2Implementation::Finish() {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
   FinishHelper();
+  if (!surface_visible_ && free_everything_when_invisible_)
+    FreeEverything();
 }
 
 void GLES2Implementation::ShallowFinishCHROMIUM() {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
+  TRACE_EVENT0("gpu", "GLES2::ShallowFinishCHROMIUM");
   // Flush our command buffer (tell the service to execute up to the flush cmd
   // and don't return until it completes).
   helper_->CommandBufferHelper::Finish();
@@ -862,7 +880,7 @@ bool GLES2Implementation::MustBeContextLost() {
     WaitForCmd();
     context_lost = helper_->IsContextLost();
   }
-  GPU_CHECK(context_lost);
+  CHECK(context_lost);
   return context_lost;
 }
 
@@ -1046,7 +1064,7 @@ bool GLES2Implementation::DeleteProgramHelper(GLuint program) {
 
 void GLES2Implementation::DeleteProgramStub(
     GLsizei n, const GLuint* programs) {
-  GPU_DCHECK_EQ(1, n);
+  DCHECK_EQ(1, n);
   share_group_->program_info_manager()->DeleteInfo(programs[0]);
   helper_->DeleteProgram(programs[0]);
 }
@@ -1064,7 +1082,7 @@ bool GLES2Implementation::DeleteShaderHelper(GLuint shader) {
 
 void GLES2Implementation::DeleteShaderStub(
     GLsizei n, const GLuint* shaders) {
-  GPU_DCHECK_EQ(1, n);
+  DCHECK_EQ(1, n);
   share_group_->program_info_manager()->DeleteInfo(shaders[0]);
   helper_->DeleteShader(shaders[0]);
 }
@@ -1210,13 +1228,13 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
     case GL_UNPACK_ALIGNMENT:
         unpack_alignment_ = param;
         break;
-    case GL_UNPACK_ROW_LENGTH:
+    case GL_UNPACK_ROW_LENGTH_EXT:
         unpack_row_length_ = param;
         return;
-    case GL_UNPACK_SKIP_ROWS:
+    case GL_UNPACK_SKIP_ROWS_EXT:
         unpack_skip_rows_ = param;
         return;
-    case GL_UNPACK_SKIP_PIXELS:
+    case GL_UNPACK_SKIP_PIXELS_EXT:
         unpack_skip_pixels_ = param;
         return;
     case GL_UNPACK_FLIP_Y_CHROMIUM:
@@ -1339,7 +1357,7 @@ void GLES2Implementation::ShaderSource(
     }
   }
 
-  GPU_DCHECK_EQ(total_size, offset);
+  DCHECK_EQ(total_size, offset);
 
   helper_->ShaderSourceBucket(shader, kResultBucketId);
   helper_->SetBucketSize(kResultBucketId, 0);
@@ -1370,7 +1388,7 @@ void GLES2Implementation::BufferDataHelper(
 
     // Create new buffer.
     buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
-    GPU_DCHECK(buffer);
+    DCHECK(buffer);
     if (buffer->address() && data)
       memcpy(buffer->address(), data, size);
     return;
@@ -1462,8 +1480,8 @@ void GLES2Implementation::BufferSubDataHelper(
 void GLES2Implementation::BufferSubDataHelperImpl(
     GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
     ScopedTransferBufferPtr* buffer) {
-  GPU_DCHECK(buffer);
-  GPU_DCHECK_GT(size, 0);
+  DCHECK(buffer);
+  DCHECK_GT(size, 0);
 
   const int8* source = static_cast<const int8*>(data);
   while (size) {
@@ -1843,7 +1861,7 @@ void GLES2Implementation::TexSubImage2D(
 static GLint ComputeNumRowsThatFitInBuffer(
     GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size,
     unsigned int size) {
-  GPU_DCHECK_GE(unpadded_row_size, 0);
+  DCHECK_GE(unpadded_row_size, 0);
   if (padded_row_size == 0) {
     return 1;
   }
@@ -1856,10 +1874,10 @@ void GLES2Implementation::TexSubImage2DImpl(
     GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size,
     const void* pixels, uint32 pixels_padded_row_size, GLboolean internal,
     ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size) {
-  GPU_DCHECK(buffer);
-  GPU_DCHECK_GE(level, 0);
-  GPU_DCHECK_GT(height, 0);
-  GPU_DCHECK_GT(width, 0);
+  DCHECK(buffer);
+  DCHECK_GE(level, 0);
+  DCHECK_GT(height, 0);
+  DCHECK_GT(width, 0);
 
   const int8* source = reinterpret_cast<const int8*>(pixels);
   GLint original_yoffset = yoffset;
@@ -2128,10 +2146,8 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
       case GL_EXTENSIONS:
         str += std::string(str.empty() ? "" : " ") +
             "GL_CHROMIUM_flipy "
-            "GL_CHROMIUM_map_sub "
-            "GL_CHROMIUM_shallow_flush "
             "GL_EXT_unpack_subimage";
-        if (gpu_control_->SupportsGpuMemoryBuffer()) {
+        if (capabilities_.map_image) {
           // The first space character is intentional.
           str += " GL_CHROMIUM_map_image";
         }
@@ -2148,7 +2164,7 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
       std::set<std::string> strings;
       std::pair<GLStringMap::iterator, bool> insert_result =
           gl_strings_.insert(std::make_pair(name, strings));
-      GPU_DCHECK(insert_result.second);
+      DCHECK(insert_result.second);
       it = insert_result.first;
     }
     std::set<std::string>& string_set = it->second;
@@ -2158,7 +2174,7 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
     } else {
       std::pair<std::set<std::string>::const_iterator, bool> insert_result =
           string_set.insert(str);
-      GPU_DCHECK(insert_result.second);
+      DCHECK(insert_result.second);
       result = insert_result.first->c_str();
     }
   }
@@ -2759,6 +2775,32 @@ void GLES2Implementation::GetVertexAttribiv(
   CheckGLError();
 }
 
+void GLES2Implementation::Swap() {
+  SwapBuffers();
+  gpu_control_->Echo(
+      base::Bind(&GLES2Implementation::OnSwapBuffersComplete,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+void GLES2Implementation::PartialSwapBuffers(const gfx::Rect& sub_buffer) {
+  PostSubBufferCHROMIUM(sub_buffer.x(),
+                        sub_buffer.y(),
+                        sub_buffer.width(),
+                        sub_buffer.height());
+  gpu_control_->Echo(base::Bind(&GLES2Implementation::OnSwapBuffersComplete,
+                                weak_ptr_factory_.GetWeakPtr()));
+}
+
+void GLES2Implementation::SetSwapBuffersCompleteCallback(
+      const base::Closure& swap_buffers_complete_callback) {
+  swap_buffers_complete_callback_ = swap_buffers_complete_callback;
+}
+
+void GLES2Implementation::OnSwapBuffersComplete() {
+  if (!swap_buffers_complete_callback_.is_null())
+    swap_buffers_complete_callback_.Run();
+}
+
 GLboolean GLES2Implementation::EnableFeatureCHROMIUM(
     const char* feature) {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
@@ -2810,7 +2852,7 @@ void* GLES2Implementation::MapBufferSubDataCHROMIUM(
          mem,
          MappedBuffer(
              access, shm_id, mem, shm_offset, target, offset, size)));
-  GPU_DCHECK(result.second);
+  DCHECK(result.second);
   GPU_CLIENT_LOG("  returned " << mem);
   return mem;
 }
@@ -2884,7 +2926,7 @@ void* GLES2Implementation::MapTexSubImage2DCHROMIUM(
          MappedTexture(
              access, shm_id, mem, shm_offset,
              target, level, xoffset, yoffset, width, height, format, type)));
-  GPU_DCHECK(result.second);
+  DCHECK(result.second);
   GPU_CLIENT_LOG("  returned " << mem);
   return mem;
 }
@@ -2940,7 +2982,7 @@ const GLchar* GLES2Implementation::GetRequestableExtensionsCHROMIUM() {
     } else {
       std::pair<std::set<std::string>::const_iterator, bool> insert_result =
           requestable_extensions_set_.insert(str);
-      GPU_DCHECK(insert_result.second);
+      DCHECK(insert_result.second);
       result = insert_result.first->c_str();
     }
   }
@@ -3122,7 +3164,7 @@ void GLES2Implementation::GetAllShaderPrecisionFormatsOnCompleted(
 
 void GLES2Implementation::GetProgramInfoCHROMIUMHelper(
     GLuint program, std::vector<int8>* result) {
-  GPU_DCHECK(result);
+  DCHECK(result);
   // Clear the bucket so if the command fails nothing will be in it.
   helper_->SetBucketSize(kResultBucketId, 0);
   helper_->GetProgramInfoCHROMIUM(program, kResultBucketId);
@@ -3143,7 +3185,7 @@ void GLES2Implementation::GetProgramInfoCHROMIUM(
   }
   // Make sure they've set size to 0 else the value will be undefined on
   // lost context.
-  GPU_DCHECK(*size == 0);
+  DCHECK(*size == 0);
   std::vector<int8> result;
   GetProgramInfoCHROMIUMHelper(program, &result);
   if (result.empty()) {
@@ -3166,29 +3208,8 @@ GLuint GLES2Implementation::CreateStreamTextureCHROMIUM(GLuint texture) {
   GPU_CLIENT_LOG("[" << GetLogPrefix() << "] CreateStreamTextureCHROMIUM("
       << texture << ")");
   TRACE_EVENT0("gpu", "GLES2::CreateStreamTextureCHROMIUM");
-  typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_ZERO;
-  }
-  *result = GL_ZERO;
-
-  helper_->CreateStreamTextureCHROMIUM(texture,
-                                       GetResultShmId(),
-                                       GetResultShmOffset());
-  WaitForCmd();
-  GLuint result_value = *result;
-  CheckGLError();
-  return result_value;
-}
-
-void GLES2Implementation::DestroyStreamTextureCHROMIUM(GLuint texture) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] DestroyStreamTextureCHROMIUM("
-      << texture << ")");
-  TRACE_EVENT0("gpu", "GLES2::DestroyStreamTextureCHROMIUM");
-  helper_->DestroyStreamTextureCHROMIUM(texture);
-  CheckGLError();
+  helper_->CommandBufferHelper::Flush();
+  return gpu_control_->CreateStreamTexture(texture);
 }
 
 void GLES2Implementation::PostSubBufferCHROMIUM(
@@ -3248,7 +3269,8 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
                  << ", " << id << ")");
 
   // if any outstanding queries INV_OP
-  if (current_query_) {
+  QueryMap::iterator it = current_queries_.find(target);
+  if (it != current_queries_.end()) {
     SetGLError(
         GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
     return;
@@ -3276,7 +3298,7 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
     return;
   }
 
-  current_query_ = query;
+  current_queries_[target] = query;
 
   query->Begin(this);
   CheckGLError();
@@ -3291,19 +3313,15 @@ void GLES2Implementation::EndQueryEXT(GLenum target) {
     return;
   }
 
-  if (!current_query_) {
+  QueryMap::iterator it = current_queries_.find(target);
+  if (it == current_queries_.end()) {
     SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "no active query");
     return;
   }
 
-  if (current_query_->target() != target) {
-    SetGLError(GL_INVALID_OPERATION,
-               "glEndQueryEXT", "target does not match active query");
-    return;
-  }
-
-  current_query_->End(this);
-  current_query_ = NULL;
+  QueryTracker::Query* query = it->second;
+  query->End(this);
+  current_queries_.erase(it);
   CheckGLError();
 }
 
@@ -3319,8 +3337,13 @@ void GLES2Implementation::GetQueryivEXT(
     SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname");
     return;
   }
-  *params = (current_query_ && current_query_->target() == target) ?
-      current_query_->id() : 0;
+  QueryMap::iterator it = current_queries_.find(target);
+  if (it != current_queries_.end()) {
+    QueryTracker::Query* query = it->second;
+    *params = query->id();
+  } else {
+    *params = 0;
+  }
   GPU_CLIENT_LOG("  " << *params);
   CheckGLError();
 }
@@ -3338,7 +3361,8 @@ void GLES2Implementation::GetQueryObjectuivEXT(
     return;
   }
 
-  if (query == current_query_) {
+  QueryMap::iterator it = current_queries_.find(query->target());
+  if (it != current_queries_.end()) {
     SetGLError(
         GL_INVALID_OPERATION,
         "glQueryObjectuivEXT", "query active. Did you to call glEndQueryEXT?");
@@ -3359,7 +3383,7 @@ void GLES2Implementation::GetQueryObjectuivEXT(
         if (!query->CheckResultsAvailable(helper_)) {
           // TODO(gman): Speed this up.
           WaitForCmd();
-          GPU_CHECK(query->CheckResultsAvailable(helper_));
+          CHECK(query->CheckResultsAvailable(helper_));
         }
       }
       *params = query->GetResult();
@@ -3448,12 +3472,34 @@ void GLES2Implementation::GenMailboxCHROMIUM(
       << static_cast<const void*>(mailbox) << ")");
   TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM");
 
-  std::vector<gpu::Mailbox> names;
-  if (!gpu_control_->GenerateMailboxNames(1, &names)) {
-    SetGLError(GL_OUT_OF_MEMORY, "glGenMailboxCHROMIUM", "Generate failed.");
-    return;
-  }
-  memcpy(mailbox, names[0].name, GL_MAILBOX_SIZE_CHROMIUM);
+  gpu::Mailbox result = gpu::Mailbox::Generate();
+  memcpy(mailbox, result.name, sizeof(result.name));
+}
+
+void GLES2Implementation::ProduceTextureCHROMIUM(GLenum target,
+                                                 const GLbyte* data) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glProduceTextureCHROMIUM("
+                     << static_cast<const void*>(data) << ")");
+  const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+  DCHECK(mailbox.Verify()) << "ProduceTextureCHROMIUM was passed a "
+                              "mailbox that was not generated by "
+                              "GenMailboxCHROMIUM.";
+  helper_->ProduceTextureCHROMIUMImmediate(target, data);
+  CheckGLError();
+}
+
+void GLES2Implementation::ConsumeTextureCHROMIUM(GLenum target,
+                                                 const GLbyte* data) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glConsumeTextureCHROMIUM("
+                     << static_cast<const void*>(data) << ")");
+  const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+  DCHECK(mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
+                              "mailbox that was not generated by "
+                              "GenMailboxCHROMIUM.";
+  helper_->ConsumeTextureCHROMIUMImmediate(target, data);
+  CheckGLError();
 }
 
 void GLES2Implementation::PushGroupMarkerEXT(