diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-25 22:30:21 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-25 22:30:21 +0000 |
commit | 33e9e431f5fcfbb007d77eec4eaed05fdc86fece (patch) | |
tree | 6b355734320de3ba8d7467e009d33ee9dfcdec04 | |
parent | 4cafbe2f1adabd8e6951a91d69697264cf281f14 (diff) | |
download | chromium_src-33e9e431f5fcfbb007d77eec4eaed05fdc86fece.zip chromium_src-33e9e431f5fcfbb007d77eec4eaed05fdc86fece.tar.gz chromium_src-33e9e431f5fcfbb007d77eec4eaed05fdc86fece.tar.bz2 |
aw: Add and use DrawGL kModeSync
We need to support this new hidden api to avoid onDraw getting ahead of
DrawGL. Without this, onDraw can finish producing frame n+1 before DrawGL
consumes frame n, in which case DrawGL skips a frame.
Also make AwDrawGLInfo future proof.
BUG=397358
Review URL: https://codereview.chromium.org/414163002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285712 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | android_webview/browser/hardware_renderer.cc | 107 | ||||
-rw-r--r-- | android_webview/browser/hardware_renderer.h | 1 | ||||
-rw-r--r-- | android_webview/native/aw_contents.cc | 7 | ||||
-rw-r--r-- | android_webview/public/browser/draw_gl.h | 6 |
4 files changed, 69 insertions, 52 deletions
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index 511969e..eaf34a9 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -76,11 +76,13 @@ HardwareRenderer::HardwareRenderer(SharedRendererState* state) last_egl_context_(eglGetCurrentContext()), stencil_enabled_(false), viewport_clip_valid_for_dcheck_(false), + gl_surface_(new AwGLSurface), root_layer_(cc::Layer::Create()), + resource_collection_(new cc::DelegatedFrameResourceCollection), output_surface_(NULL) { DCHECK(last_egl_context_); - gl_surface_ = new AwGLSurface; + resource_collection_->SetClient(this); cc::LayerTreeSettings settings; @@ -105,17 +107,15 @@ HardwareRenderer::~HardwareRenderer() { root_layer_ = NULL; delegated_layer_ = NULL; frame_provider_ = NULL; - if (resource_collection_.get()) { #if DCHECK_IS_ON - // Check collection is empty. - cc::ReturnedResourceArray returned_resources; - resource_collection_->TakeUnusedResourcesForChildCompositor( - &returned_resources); - DCHECK_EQ(0u, returned_resources.size()); + // Check collection is empty. + cc::ReturnedResourceArray returned_resources; + resource_collection_->TakeUnusedResourcesForChildCompositor( + &returned_resources); + DCHECK_EQ(0u, returned_resources.size()); #endif // DCHECK_IS_ON - resource_collection_->SetClient(NULL); - } + resource_collection_->SetClient(NULL); } void HardwareRenderer::DidBeginMainFrame() { @@ -127,6 +127,48 @@ void HardwareRenderer::DidBeginMainFrame() { output_surface_->SetDrawConstraints(viewport_, clip_); } +void HardwareRenderer::CommitFrame() { + scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput(); + if (!input.get()) { + DLOG(WARNING) << "No frame to commit"; + return; + } + + DCHECK(!input->frame.gl_frame_data); + DCHECK(!input->frame.software_frame_data); + + // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the + // renderer frame, assuming that the browser compositor will scale + // it back up to device scale. But on Android we put our browser layers in + // physical pixels and set our browser CC device_scale_factor to 1, so this + // suppresses the transform. + input->frame.delegated_frame_data->device_scale_factor = 1.0f; + + gfx::Size frame_size = + input->frame.delegated_frame_data->render_pass_list.back() + ->output_rect.size(); + bool size_changed = frame_size != frame_size_; + frame_size_ = frame_size; + scroll_offset_ = input->scroll_offset; + + if (!frame_provider_ || size_changed) { + if (delegated_layer_) { + delegated_layer_->RemoveFromParent(); + } + + frame_provider_ = new cc::DelegatedFrameProvider( + resource_collection_.get(), input->frame.delegated_frame_data.Pass()); + + delegated_layer_ = cc::DelegatedRendererLayer::Create(frame_provider_); + delegated_layer_->SetBounds(gfx::Size(input->width, input->height)); + delegated_layer_->SetIsDrawable(true); + + root_layer_->AddChild(delegated_layer_); + } else { + frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass()); + } +} + void HardwareRenderer::DrawGL(bool stencil_enabled, int framebuffer_binding_ext, AwDrawGLInfo* draw_info) { @@ -140,52 +182,15 @@ void HardwareRenderer::DrawGL(bool stencil_enabled, return; } + if (!delegated_layer_.get()) { + DLOG(ERROR) << "No frame committed"; + return; + } + // TODO(boliu): Handle context loss. if (last_egl_context_ != current_context) DLOG(WARNING) << "EGLContextChanged"; - scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput(); - if (!resource_collection_.get()) { - resource_collection_ = new cc::DelegatedFrameResourceCollection; - resource_collection_->SetClient(this); - } - - if (input.get()) { - DCHECK(!input->frame.gl_frame_data); - DCHECK(!input->frame.software_frame_data); - - // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the - // renderer frame, assuming that the browser compositor will scale - // it back up to device scale. But on Android we put our browser layers in - // physical pixels and set our browser CC device_scale_factor to 1, so this - // suppresses the transform. - input->frame.delegated_frame_data->device_scale_factor = 1.0f; - - gfx::Size frame_size = - input->frame.delegated_frame_data->render_pass_list.back() - ->output_rect.size(); - bool size_changed = frame_size != frame_size_; - frame_size_ = frame_size; - scroll_offset_ = input->scroll_offset; - - if (!frame_provider_ || size_changed) { - if (delegated_layer_) { - delegated_layer_->RemoveFromParent(); - } - - frame_provider_ = new cc::DelegatedFrameProvider( - resource_collection_.get(), input->frame.delegated_frame_data.Pass()); - - delegated_layer_ = cc::DelegatedRendererLayer::Create(frame_provider_); - delegated_layer_->SetBounds(gfx::Size(input->width, input->height)); - delegated_layer_->SetIsDrawable(true); - - root_layer_->AddChild(delegated_layer_); - } else { - frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass()); - } - } - viewport_.SetSize(draw_info->width, draw_info->height); layer_tree_host_->SetViewportSize(viewport_); clip_.SetRect(draw_info->clip_left, diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 115ff0e..f69d587 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -35,6 +35,7 @@ class HardwareRenderer : public cc::LayerTreeHostClient, void DrawGL(bool stencil_enabled, int framebuffer_binding_ext, AwDrawGLInfo* draw_info); + void CommitFrame(); // cc::LayerTreeHostClient overrides. virtual void WillBeginMainFrame(int frame_id) OVERRIDE {} diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 32cc8d1..cc5e6a3 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -342,6 +342,12 @@ jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { } void AwContents::DrawGL(AwDrawGLInfo* draw_info) { + if (draw_info->mode == AwDrawGLInfo::kModeSync) { + if (hardware_renderer_) + hardware_renderer_->CommitFrame(); + return; + } + { GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); base::AutoLock lock(render_thread_lock_); @@ -366,6 +372,7 @@ void AwContents::DrawGL(AwDrawGLInfo* draw_info) { if (!hardware_renderer_) { hardware_renderer_.reset(new HardwareRenderer(&shared_renderer_state_)); + hardware_renderer_->CommitFrame(); } hardware_renderer_->DrawGL(state_restore.stencil_enabled(), diff --git a/android_webview/public/browser/draw_gl.h b/android_webview/public/browser/draw_gl.h index 6409598..4a43523 100644 --- a/android_webview/public/browser/draw_gl.h +++ b/android_webview/public/browser/draw_gl.h @@ -9,11 +9,15 @@ extern "C" { #endif +static const int kAwDrawGLInfoVersion = 1; + // Holds the information required to trigger an OpenGL drawing operation. struct AwDrawGLInfo { + int version; // The AwDrawGLInfo this struct was built with. + // Input: tells the draw function what action to perform. enum Mode { - kModeDraw, + kModeDraw = 0, kModeProcess, kModeProcessNoContext, kModeSync, |