summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 22:30:21 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 22:30:21 +0000
commit33e9e431f5fcfbb007d77eec4eaed05fdc86fece (patch)
tree6b355734320de3ba8d7467e009d33ee9dfcdec04
parent4cafbe2f1adabd8e6951a91d69697264cf281f14 (diff)
downloadchromium_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.cc107
-rw-r--r--android_webview/browser/hardware_renderer.h1
-rw-r--r--android_webview/native/aw_contents.cc7
-rw-r--r--android_webview/public/browser/draw_gl.h6
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,