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

Unified Diff: android_webview/browser/shared_renderer_state.cc

Issue 653173004: Part 2: WIP Refactor Webview graphics related code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rewrite rebase, without renames Created 6 years, 2 months 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: android_webview/browser/shared_renderer_state.cc
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc
index da12c34f993b8792857b7d9ea07013bd2f274dc6..1bcc482e0caca19dc762f17312c391d78b96d082 100644
--- a/android_webview/browser/shared_renderer_state.cc
+++ b/android_webview/browser/shared_renderer_state.cc
@@ -5,6 +5,10 @@
#include "android_webview/browser/shared_renderer_state.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"
@@ -72,6 +76,7 @@ SharedRendererState::SharedRendererState(
BrowserViewRenderer* browser_view_renderer)
: ui_loop_(ui_loop),
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),
@@ -84,13 +89,14 @@ SharedRendererState::SharedRendererState(
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().ShouldRequestOnNonUiThread(this))
return;
@@ -110,13 +116,12 @@ 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 (!browser_view_renderer_->RequestDrawGL(false)) {
@@ -125,7 +130,7 @@ void SharedRendererState::ClientRequestDrawGLOnUIThread() {
}
}
-void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() {
+void SharedRendererState::UpdateParentDrawConstraintsOnUI() {
DCHECK(ui_loop_->BelongsToCurrentThread());
browser_view_renderer_->UpdateParentDrawConstraints();
}
@@ -148,13 +153,15 @@ bool SharedRendererState::HasCompositorFrameOnUI() const {
void SharedRendererState::SetCompositorFrameOnUI(
scoped_ptr<cc::CompositorFrame> frame,
bool force_commit) {
+ ReturnUnusedResourceOnUI();
+
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();
}
@@ -182,7 +189,7 @@ void SharedRendererState::PostExternalDrawConstraintsToChildCompositorOnRT(
// 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_));
}
}
@@ -226,6 +233,22 @@ bool SharedRendererState::IsInsideHardwareRelease() const {
return inside_hardware_release_;
}
+void SharedRendererState::ReturnUnusedResourceOnUI() {
+ DCHECK(ui_loop_->BelongsToCurrentThread());
+ base::AutoLock lock(lock_);
+
+ scoped_ptr<cc::CompositorFrame> frame;
+ frame = compositor_frame_.Pass();
+
+ if (frame.get()) {
+ cc::ReturnedResourceArray resources;
+ cc::TransferableResource::ReturnResources(
+ frame->delegated_frame_data->resource_list, &resources);
+ returned_resources_.insert(
+ returned_resources_.end(), resources.begin(), resources.end());
+ }
+}
+
void SharedRendererState::InsertReturnedResourcesOnRT(
const cc::ReturnedResourceArray& resources) {
base::AutoLock lock(lock_);
@@ -240,20 +263,122 @@ void SharedRendererState::SwapReturnedResourcesOnUI(
resources->swap(returned_resources_);
}
-bool SharedRendererState::ReturnedResourcesEmpty() const {
+bool SharedRendererState::ReturnedResourcesEmptyOnUI() const {
base::AutoLock lock(lock_);
return returned_resources_.empty();
}
-InsideHardwareReleaseReset::InsideHardwareReleaseReset(
- SharedRendererState* shared_renderer_state)
- : shared_renderer_state_(shared_renderer_state) {
- DCHECK(!shared_renderer_state_->IsInsideHardwareRelease());
- shared_renderer_state_->SetInsideHardwareRelease(true);
+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);
}
-InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
- shared_renderer_state_->SetInsideHardwareRelease(false);
+void SharedRendererState::ReleaseHardwareDrawIfNeededOnUI() {
+ DCHECK(ui_loop_->BelongsToCurrentThread());
+ SetInsideHardwareRelease(true);
boliu 2014/10/28 19:49:43 Keep using a scoped var to enforce this. Now it ca
hush (inactive) 2014/10/29 19:57:04 Done.
+
+ 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);
+ }
+
+ ReturnUnusedResourceOnUI();
+
+ browser_view_renderer_->ReleaseHardware();
+ }
+ // TODO(hush): Need to acquire the lock for the DCHECK because
+ // hardware_renderer_ is reset on RT?
boliu 2014/10/28 19:49:43 Technically yes, but that would mean also locking
hush (inactive) 2014/10/29 19:57:04 Removed this DCHECK.
+ DCHECK(!hardware_renderer_);
+
+ 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 OnDetachedFromWindow.
boliu 2014/10/28 19:49:43 s/OnDetachedFromWindow/ReleaseHardware/
hush (inactive) 2014/10/29 19:57:04 Done.
+ browser_view_renderer_->RequestDrawGL(true);
+ }
+
+ SetInsideHardwareRelease(false);
+}
+
+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();
+ }
}
} // namespace android_webview

Powered by Google App Engine
This is Rietveld 408576698