Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / android_webview / browser / shared_renderer_state.cc
index 0de8371..52e3479 100644 (file)
@@ -4,7 +4,11 @@
 
 #include "android_webview/browser/shared_renderer_state.h"
 
-#include "android_webview/browser/browser_view_renderer_client.h"
+#include "android_webview/browser/browser_view_renderer.h"
+#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/browser/hardware_renderer.h"
+#include "android_webview/browser/scoped_app_gl_state_restore.h"
+#include "android_webview/public/browser/draw_gl.h"
 #include "base/bind.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
@@ -16,7 +20,7 @@ namespace internal {
 class RequestDrawGLTracker {
  public:
   RequestDrawGLTracker();
-  bool ShouldRequestOnNoneUiThread(SharedRendererState* state);
+  bool ShouldRequestOnNonUiThread(SharedRendererState* state);
   bool ShouldRequestOnUiThread(SharedRendererState* state);
   void DidRequestOnUiThread();
   void ResetPending();
@@ -31,7 +35,7 @@ RequestDrawGLTracker::RequestDrawGLTracker()
     : pending_ui_(NULL), pending_non_ui_(NULL) {
 }
 
-bool RequestDrawGLTracker::ShouldRequestOnNoneUiThread(
+bool RequestDrawGLTracker::ShouldRequestOnNonUiThread(
     SharedRendererState* state) {
   base::AutoLock lock(lock_);
   if (pending_ui_ || pending_non_ui_)
@@ -68,31 +72,33 @@ base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker =
 }
 
 SharedRendererState::SharedRendererState(
-    scoped_refptr<base::MessageLoopProxy> ui_loop,
-    BrowserViewRendererClient* client)
+    const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop,
+    BrowserViewRenderer* browser_view_renderer)
     : ui_loop_(ui_loop),
-      client_on_ui_(client),
+      browser_view_renderer_(browser_view_renderer),
+      renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()),
       force_commit_(false),
       inside_hardware_release_(false),
       needs_force_invalidate_on_next_draw_gl_(false),
       weak_factory_on_ui_thread_(this) {
   DCHECK(ui_loop_->BelongsToCurrentThread());
-  DCHECK(client_on_ui_);
+  DCHECK(browser_view_renderer_);
   ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr();
   ResetRequestDrawGLCallback();
 }
 
 SharedRendererState::~SharedRendererState() {
   DCHECK(ui_loop_->BelongsToCurrentThread());
+  DCHECK(!hardware_renderer_.get());
 }
 
 void SharedRendererState::ClientRequestDrawGL() {
   if (ui_loop_->BelongsToCurrentThread()) {
     if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this))
       return;
-    ClientRequestDrawGLOnUIThread();
+    ClientRequestDrawGLOnUI();
   } else {
-    if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNoneUiThread(this))
+    if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNonUiThread(this))
       return;
     base::Closure callback;
     {
@@ -110,60 +116,66 @@ void SharedRendererState::DidDrawGLProcess() {
 void SharedRendererState::ResetRequestDrawGLCallback() {
   DCHECK(ui_loop_->BelongsToCurrentThread());
   base::AutoLock lock(lock_);
-  request_draw_gl_cancelable_closure_.Reset(
-      base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread,
-                 base::Unretained(this)));
+  request_draw_gl_cancelable_closure_.Reset(base::Bind(
+      &SharedRendererState::ClientRequestDrawGLOnUI, base::Unretained(this)));
   request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback();
 }
 
-void SharedRendererState::ClientRequestDrawGLOnUIThread() {
+void SharedRendererState::ClientRequestDrawGLOnUI() {
   DCHECK(ui_loop_->BelongsToCurrentThread());
   ResetRequestDrawGLCallback();
-  if (!client_on_ui_->RequestDrawGL(NULL, false)) {
+  if (!browser_view_renderer_->RequestDrawGL(false)) {
     g_request_draw_gl_tracker.Get().ResetPending();
     LOG(ERROR) << "Failed to request GL process. Deadlock likely";
   }
 }
 
-void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() {
+void SharedRendererState::UpdateParentDrawConstraintsOnUI() {
   DCHECK(ui_loop_->BelongsToCurrentThread());
-  client_on_ui_->UpdateParentDrawConstraints();
+  browser_view_renderer_->UpdateParentDrawConstraints();
 }
 
-void SharedRendererState::SetScrollOffset(gfx::Vector2d scroll_offset) {
+void SharedRendererState::SetScrollOffsetOnUI(gfx::Vector2d scroll_offset) {
   base::AutoLock lock(lock_);
   scroll_offset_ = scroll_offset;
 }
 
-gfx::Vector2d SharedRendererState::GetScrollOffset() {
+gfx::Vector2d SharedRendererState::GetScrollOffsetOnRT() {
   base::AutoLock lock(lock_);
   return scroll_offset_;
 }
 
-bool SharedRendererState::HasCompositorFrame() const {
+bool SharedRendererState::HasCompositorFrameOnUI() const {
   base::AutoLock lock(lock_);
   return compositor_frame_.get();
 }
 
-void SharedRendererState::SetCompositorFrame(
-    scoped_ptr<cc::CompositorFrame> frame, bool force_commit) {
+void SharedRendererState::SetCompositorFrameOnUI(
+    scoped_ptr<cc::CompositorFrame> frame,
+    bool force_commit) {
   base::AutoLock lock(lock_);
   DCHECK(!compositor_frame_.get());
   compositor_frame_ = frame.Pass();
   force_commit_ = force_commit;
 }
 
-scoped_ptr<cc::CompositorFrame> SharedRendererState::PassCompositorFrame() {
+scoped_ptr<cc::CompositorFrame> SharedRendererState::PassCompositorFrameOnRT() {
   base::AutoLock lock(lock_);
   return compositor_frame_.Pass();
 }
 
-bool SharedRendererState::ForceCommit() const {
+scoped_ptr<cc::CompositorFrame>
+SharedRendererState::PassUncommittedFrameOnUI() {
+  base::AutoLock lock(lock_);
+  return compositor_frame_.Pass();
+}
+
+bool SharedRendererState::ForceCommitOnRT() const {
   base::AutoLock lock(lock_);
   return force_commit_;
 }
 
-bool SharedRendererState::UpdateDrawConstraints(
+bool SharedRendererState::UpdateDrawConstraintsOnRT(
     const ParentCompositorDrawConstraints& parent_draw_constraints) {
   base::AutoLock lock(lock_);
   if (needs_force_invalidate_on_next_draw_gl_ ||
@@ -175,43 +187,42 @@ bool SharedRendererState::UpdateDrawConstraints(
   return false;
 }
 
-void SharedRendererState::PostExternalDrawConstraintsToChildCompositor(
+void SharedRendererState::PostExternalDrawConstraintsToChildCompositorOnRT(
     const ParentCompositorDrawConstraints& parent_draw_constraints) {
-  if (UpdateDrawConstraints(parent_draw_constraints)) {
+  if (UpdateDrawConstraintsOnRT(parent_draw_constraints)) {
     // No need to hold the lock_ during the post task.
     ui_loop_->PostTask(
         FROM_HERE,
-        base::Bind(&SharedRendererState::UpdateParentDrawConstraintsOnUIThread,
+        base::Bind(&SharedRendererState::UpdateParentDrawConstraintsOnUI,
                    ui_thread_weak_ptr_));
   }
 }
 
-void SharedRendererState::DidSkipCommitFrame() {
-  ui_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(&SharedRendererState::DidSkipCommitFrameOnUIThread,
-                 ui_thread_weak_ptr_));
+void SharedRendererState::DidSkipCommitFrameOnRT() {
+  ui_loop_->PostTask(FROM_HERE,
+                     base::Bind(&SharedRendererState::DidSkipCommitFrameOnUI,
+                                ui_thread_weak_ptr_));
 }
 
-void SharedRendererState::DidSkipCommitFrameOnUIThread() {
+void SharedRendererState::DidSkipCommitFrameOnUI() {
   DCHECK(ui_loop_->BelongsToCurrentThread());
-  client_on_ui_->DidSkipCommitFrame();
+  browser_view_renderer_->DidSkipCommitFrame();
 }
 
-const ParentCompositorDrawConstraints
-SharedRendererState::ParentDrawConstraints() const {
+ParentCompositorDrawConstraints
+SharedRendererState::GetParentDrawConstraintsOnUI() const {
   base::AutoLock lock(lock_);
   return parent_draw_constraints_;
 }
 
-void SharedRendererState::SetForceInvalidateOnNextDrawGL(
+void SharedRendererState::SetForceInvalidateOnNextDrawGLOnUI(
     bool needs_force_invalidate_on_next_draw_gl) {
   base::AutoLock lock(lock_);
   needs_force_invalidate_on_next_draw_gl_ =
       needs_force_invalidate_on_next_draw_gl;
 }
 
-bool SharedRendererState::NeedsForceInvalidateOnNextDrawGL() const {
+bool SharedRendererState::NeedsForceInvalidateOnNextDrawGLOnUI() const {
   base::AutoLock lock(lock_);
   return needs_force_invalidate_on_next_draw_gl_;
 }
@@ -226,33 +237,139 @@ bool SharedRendererState::IsInsideHardwareRelease() const {
   return inside_hardware_release_;
 }
 
-void SharedRendererState::InsertReturnedResources(
+void SharedRendererState::InsertReturnedResourcesOnRT(
     const cc::ReturnedResourceArray& resources) {
   base::AutoLock lock(lock_);
   returned_resources_.insert(
       returned_resources_.end(), resources.begin(), resources.end());
 }
 
-void SharedRendererState::SwapReturnedResources(
+void SharedRendererState::SwapReturnedResourcesOnUI(
     cc::ReturnedResourceArray* resources) {
   DCHECK(resources->empty());
   base::AutoLock lock(lock_);
   resources->swap(returned_resources_);
 }
 
-bool SharedRendererState::ReturnedResourcesEmpty() const {
+bool SharedRendererState::ReturnedResourcesEmptyOnUI() const {
   base::AutoLock lock(lock_);
   return returned_resources_.empty();
 }
 
-InsideHardwareReleaseReset::InsideHardwareReleaseReset(
+void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) {
+  if (draw_info->mode == AwDrawGLInfo::kModeSync) {
+    if (hardware_renderer_)
+      hardware_renderer_->CommitFrame();
+    return;
+  }
+
+  {
+    GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
+    base::AutoLock lock(lock_);
+    if (renderer_manager_key_ != manager->NullKey()) {
+      manager->DidDrawGL(renderer_manager_key_);
+    }
+  }
+
+  ScopedAppGLStateRestore state_restore(
+      draw_info->mode == AwDrawGLInfo::kModeDraw
+          ? ScopedAppGLStateRestore::MODE_DRAW
+          : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
+  ScopedAllowGL allow_gl;
+
+  if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
+    LOG(ERROR) << "Received unexpected kModeProcessNoContext";
+  }
+
+  // kModeProcessNoContext should never happen because we tear down hardware
+  // in onTrimMemory. However that guarantee is maintained outside of chromium
+  // code. Not notifying shared state in kModeProcessNoContext can lead to
+  // immediate deadlock, which is slightly more catastrophic than leaks or
+  // corruption.
+  if (draw_info->mode == AwDrawGLInfo::kModeProcess ||
+      draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
+    DidDrawGLProcess();
+  }
+
+  if (IsInsideHardwareRelease()) {
+    hardware_renderer_.reset();
+    // Flush the idle queue in tear down.
+    DeferredGpuCommandService::GetInstance()->PerformAllIdleWork();
+    return;
+  }
+
+  if (draw_info->mode != AwDrawGLInfo::kModeDraw) {
+    if (draw_info->mode == AwDrawGLInfo::kModeProcess) {
+      DeferredGpuCommandService::GetInstance()->PerformIdleWork(true);
+    }
+    return;
+  }
+
+  if (!hardware_renderer_) {
+    hardware_renderer_.reset(new HardwareRenderer(this));
+    hardware_renderer_->CommitFrame();
+  }
+
+  hardware_renderer_->DrawGL(state_restore.stencil_enabled(),
+                             state_restore.framebuffer_binding_ext(),
+                             draw_info);
+  DeferredGpuCommandService::GetInstance()->PerformIdleWork(false);
+}
+
+void SharedRendererState::ReleaseHardwareDrawIfNeededOnUI() {
+  DCHECK(ui_loop_->BelongsToCurrentThread());
+  InsideHardwareReleaseReset auto_inside_hardware_release_reset(this);
+
+  browser_view_renderer_->InvalidateOnFunctorDestroy();
+  bool hardware_initialized = browser_view_renderer_->hardware_enabled();
+  if (hardware_initialized) {
+    bool draw_functor_succeeded = browser_view_renderer_->RequestDrawGL(true);
+    if (!draw_functor_succeeded) {
+      LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?";
+      // Calling release on wrong thread intentionally.
+      AwDrawGLInfo info;
+      info.mode = AwDrawGLInfo::kModeProcess;
+      DrawGL(&info);
+    }
+
+    browser_view_renderer_->ReleaseHardware();
+  }
+
+  GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
+
+  {
+    base::AutoLock lock(lock_);
+    if (renderer_manager_key_ != manager->NullKey()) {
+      manager->Remove(renderer_manager_key_);
+      renderer_manager_key_ = manager->NullKey();
+    }
+  }
+
+  if (hardware_initialized) {
+    // Flush any invoke functors that's caused by ReleaseHardware.
+    browser_view_renderer_->RequestDrawGL(true);
+  }
+}
+
+void SharedRendererState::InitializeHardwareDrawIfNeededOnUI() {
+  DCHECK(ui_loop_->BelongsToCurrentThread());
+  GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
+
+  base::AutoLock lock(lock_);
+  if (renderer_manager_key_ == manager->NullKey()) {
+    renderer_manager_key_ = manager->PushBack(this);
+    DeferredGpuCommandService::SetInstance();
+  }
+}
+
+SharedRendererState::InsideHardwareReleaseReset::InsideHardwareReleaseReset(
     SharedRendererState* shared_renderer_state)
     : shared_renderer_state_(shared_renderer_state) {
   DCHECK(!shared_renderer_state_->IsInsideHardwareRelease());
   shared_renderer_state_->SetInsideHardwareRelease(true);
 }
 
-InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
+SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
   shared_renderer_state_->SetInsideHardwareRelease(false);
 }