diff options
34 files changed, 475 insertions, 76 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index cf93d1c..8f04917 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp @@ -200,6 +200,8 @@ 'browser/net/init_native_callback.h', 'browser/net/input_stream_reader.cc', 'browser/net/input_stream_reader.h', + 'browser/parent_compositor_draw_constraints.cc', + 'browser/parent_compositor_draw_constraints.h', 'browser/parent_output_surface.cc', 'browser/parent_output_surface.h', 'browser/renderer_host/aw_render_view_host_ext.cc', diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index b958dae..489794c 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -259,14 +259,29 @@ bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { draw_gl_input->width = width_; draw_gl_input->height = height_; - gfx::Transform transform; + parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); gfx::Size surface_size(width_, height_); gfx::Rect viewport(surface_size); - // TODO(boliu): Should really be |last_on_draw_global_visible_rect_|. - // See crbug.com/372073. gfx::Rect clip = viewport; - scoped_ptr<cc::CompositorFrame> frame = compositor_->DemandDrawHw( - surface_size, transform, viewport, clip); + gfx::Transform transform_for_tile_priority = + parent_draw_constraints_.transform; + + // If the WebView is on a layer, WebView does not know what transform is + // applied onto the layer so global visible rect does not make sense here. + // In this case, just use the surface rect for tiling. + gfx::Rect viewport_rect_for_tile_priority; + if (parent_draw_constraints_.is_layer) + viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; + else + viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; + + scoped_ptr<cc::CompositorFrame> frame = + compositor_->DemandDrawHw(surface_size, + gfx::Transform(), + viewport, + clip, + viewport_rect_for_tile_priority, + transform_for_tile_priority); if (!frame.get()) return false; @@ -279,6 +294,14 @@ bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { return client_->RequestDrawGL(java_canvas, false); } +void BrowserViewRenderer::UpdateParentDrawConstraints() { + // Post an invalidate if the parent draw constraints are stale and there is + // no pending invalidate. + if (!parent_draw_constraints_.Equals( + shared_renderer_state_->ParentDrawConstraints())) + EnsureContinuousInvalidation(true); +} + void BrowserViewRenderer::ReturnUnusedResource(scoped_ptr<DrawGLInput> input) { if (!input.get()) return; diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h index 338b31d..810fb81 100644 --- a/android_webview/browser/browser_view_renderer.h +++ b/android_webview/browser/browser_view_renderer.h @@ -7,6 +7,7 @@ #include "android_webview/browser/global_tile_manager.h" #include "android_webview/browser/global_tile_manager_client.h" +#include "android_webview/browser/parent_compositor_draw_constraints.h" #include "android_webview/browser/shared_renderer_state.h" #include "base/android/scoped_java_ref.h" #include "base/callback.h" @@ -140,6 +141,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient, virtual void SetNumTiles(size_t num_tiles, bool effective_immediately) OVERRIDE; + void UpdateParentDrawConstraints(); + private: void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_dip); // Checks the continuous invalidate and block invalidate state, and schedule @@ -199,6 +202,10 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient, gfx::Vector2d last_on_draw_scroll_offset_; gfx::Rect last_on_draw_global_visible_rect_; + // The draw constraints from the parent compositor. These are only used for + // tiling priority. + ParentCompositorDrawConstraints parent_draw_constraints_; + // When true, we should continuously invalidate and keep drawing, for example // to drive animation. This value is set by the compositor and should always // reflect the expectation of the compositor and not be reused for other diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/browser_view_renderer_client.h index 41fbf5a..2fba4d2 100644 --- a/android_webview/browser/browser_view_renderer_client.h +++ b/android_webview/browser/browser_view_renderer_client.h @@ -28,6 +28,9 @@ class BrowserViewRendererClient { // Called to trigger view invalidations. virtual void PostInvalidate() = 0; + // Called to update the parent draw constraints in browser view renderer. + virtual void UpdateParentDrawConstraints() = 0; + // Called to get view's absolute location on the screen. virtual gfx::Point GetLocationOnScreen() = 0; diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index eaf34a9..818d3c5 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -191,6 +191,21 @@ void HardwareRenderer::DrawGL(bool stencil_enabled, if (last_egl_context_ != current_context) DLOG(WARNING) << "EGLContextChanged"; + gfx::Transform transform(gfx::Transform::kSkipInitialization); + transform.matrix().setColMajorf(draw_info->transform); + transform.Translate(scroll_offset_.x(), scroll_offset_.y()); + + // Need to post the new transform matrix back to child compositor + // because there is no onDraw during a Render Thread animation, and child + // compositor might not have the tiles rasterized as the animation goes on. + ParentCompositorDrawConstraints draw_constraints( + draw_info->is_layer, transform, gfx::Rect(viewport_)); + if (!draw_constraints_.Equals(draw_constraints)) { + draw_constraints_ = draw_constraints; + shared_renderer_state_->PostExternalDrawConstraintsToChildCompositor( + draw_constraints); + } + viewport_.SetSize(draw_info->width, draw_info->height); layer_tree_host_->SetViewportSize(viewport_); clip_.SetRect(draw_info->clip_left, @@ -199,9 +214,6 @@ void HardwareRenderer::DrawGL(bool stencil_enabled, draw_info->clip_bottom - draw_info->clip_top); stencil_enabled_ = stencil_enabled; - gfx::Transform transform(gfx::Transform::kSkipInitialization); - transform.matrix().setColMajorf(draw_info->transform); - transform.Translate(scroll_offset_.x(), scroll_offset_.y()); delegated_layer_->SetTransform(transform); gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index f69d587..f87890b 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -5,6 +5,7 @@ #ifndef ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_ #define ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_ +#include "android_webview/browser/parent_compositor_draw_constraints.h" #include "android_webview/browser/shared_renderer_state.h" #include "base/memory/scoped_ptr.h" #include "cc/layers/delegated_frame_resource_collection.h" @@ -89,6 +90,8 @@ class HardwareRenderer : public cc::LayerTreeHostClient, // This is owned indirectly by |layer_tree_host_|. ParentOutputSurface* output_surface_; + ParentCompositorDrawConstraints draw_constraints_; + DISALLOW_COPY_AND_ASSIGN(HardwareRenderer); }; diff --git a/android_webview/browser/parent_compositor_draw_constraints.cc b/android_webview/browser/parent_compositor_draw_constraints.cc new file mode 100644 index 0000000..e507d43 --- /dev/null +++ b/android_webview/browser/parent_compositor_draw_constraints.cc @@ -0,0 +1,29 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/parent_compositor_draw_constraints.h" + +namespace android_webview { + +ParentCompositorDrawConstraints::ParentCompositorDrawConstraints() + : is_layer(false) { +} + +ParentCompositorDrawConstraints::ParentCompositorDrawConstraints( + bool is_layer, + const gfx::Transform& transform, + const gfx::Rect& surface_rect) + : is_layer(is_layer), transform(transform), surface_rect(surface_rect) { +} + +bool ParentCompositorDrawConstraints::Equals( + const ParentCompositorDrawConstraints& other) const { + if (is_layer != other.is_layer || transform != other.transform) + return false; + + // Don't care about the surface size when neither is on a layer. + return !is_layer || surface_rect == other.surface_rect; +} + +} // namespace webview diff --git a/android_webview/browser/parent_compositor_draw_constraints.h b/android_webview/browser/parent_compositor_draw_constraints.h new file mode 100644 index 0000000..4355aa9 --- /dev/null +++ b/android_webview/browser/parent_compositor_draw_constraints.h @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_ +#define ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_ + +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/transform.h" + +namespace android_webview { + +struct ParentCompositorDrawConstraints { + bool is_layer; + gfx::Transform transform; + gfx::Rect surface_rect; + + ParentCompositorDrawConstraints(); + ParentCompositorDrawConstraints(bool is_layer, + const gfx::Transform& transform, + const gfx::Rect& surface_rect); + bool Equals(const ParentCompositorDrawConstraints& other) const; +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_ diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/parent_output_surface.cc index 54b7f97..0680bc7 100644 --- a/android_webview/browser/parent_output_surface.cc +++ b/android_webview/browser/parent_output_surface.cc @@ -30,7 +30,8 @@ void ParentOutputSurface::SetDrawConstraints(const gfx::Size& surface_size, const gfx::Transform identity; const gfx::Rect empty; const bool resourceless_software_draw = false; - SetExternalDrawConstraints(identity, empty, clip, resourceless_software_draw); + SetExternalDrawConstraints( + identity, empty, clip, clip, identity, resourceless_software_draw); } } // namespace android_webview diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index 582908e..200e2ab 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc @@ -51,6 +51,11 @@ void SharedRendererState::ClientRequestDrawGLOnUIThread() { } } +void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { + DCHECK(ui_loop_->BelongsToCurrentThread()); + client_on_ui_->UpdateParentDrawConstraints(); +} + void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) { base::AutoLock lock(lock_); DCHECK(!draw_gl_input_.get()); @@ -62,6 +67,26 @@ scoped_ptr<DrawGLInput> SharedRendererState::PassDrawGLInput() { return draw_gl_input_.Pass(); } +void SharedRendererState::PostExternalDrawConstraintsToChildCompositor( + const ParentCompositorDrawConstraints& parent_draw_constraints) { + { + base::AutoLock lock(lock_); + parent_draw_constraints_ = parent_draw_constraints; + } + + // No need to hold the lock_ during the post task. + ui_loop_->PostTask( + FROM_HERE, + base::Bind(&SharedRendererState::UpdateParentDrawConstraintsOnUIThread, + ui_thread_weak_ptr_)); +} + +const ParentCompositorDrawConstraints +SharedRendererState::ParentDrawConstraints() const { + base::AutoLock lock(lock_); + return parent_draw_constraints_; +} + void SharedRendererState::SetInsideHardwareRelease(bool inside) { base::AutoLock lock(lock_); inside_hardware_release_ = inside; diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h index 01363f1..cf0c889 100644 --- a/android_webview/browser/shared_renderer_state.h +++ b/android_webview/browser/shared_renderer_state.h @@ -5,6 +5,7 @@ #ifndef ANDROID_WEBVIEW_BROWSER_SHARED_RENDERER_STATE_H_ #define ANDROID_WEBVIEW_BROWSER_SHARED_RENDERER_STATE_H_ +#include "android_webview/browser/parent_compositor_draw_constraints.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop_proxy.h" #include "base/synchronization/lock.h" @@ -50,6 +51,10 @@ class SharedRendererState { scoped_ptr<DrawGLInput> PassDrawGLInput(); bool IsInsideHardwareRelease() const; + void PostExternalDrawConstraintsToChildCompositor( + const ParentCompositorDrawConstraints& parent_draw_constraints); + + const ParentCompositorDrawConstraints ParentDrawConstraints() const; void SetSharedContext(gpu::GLInProcessContext* context); gpu::GLInProcessContext* GetSharedContext() const; @@ -62,6 +67,7 @@ class SharedRendererState { friend class InsideHardwareReleaseReset; void ClientRequestDrawGLOnUIThread(); + void UpdateParentDrawConstraintsOnUIThread(); void SetInsideHardwareRelease(bool inside); scoped_refptr<base::MessageLoopProxy> ui_loop_; @@ -73,6 +79,7 @@ class SharedRendererState { mutable base::Lock lock_; scoped_ptr<DrawGLInput> draw_gl_input_; bool inside_hardware_release_; + ParentCompositorDrawConstraints parent_draw_constraints_; gpu::GLInProcessContext* share_context_; cc::ReturnedResourceArray returned_resources_; diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index e1186fc..5cecb00 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -751,6 +751,11 @@ void AwContents::PostInvalidate() { Java_AwContents_postInvalidateOnAnimation(env, obj.obj()); } +void AwContents::UpdateParentDrawConstraints() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + browser_view_renderer_.UpdateParentDrawConstraints(); +} + void AwContents::OnNewPicture() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); JNIEnv* env = AttachCurrentThread(); diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index ddfeaf3..1381007 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -192,6 +192,7 @@ class AwContents : public FindHelper::Listener, // BrowserViewRendererClient implementation. virtual bool RequestDrawGL(jobject canvas, bool wait_for_completion) OVERRIDE; virtual void PostInvalidate() OVERRIDE; + virtual void UpdateParentDrawConstraints() OVERRIDE; virtual void OnNewPicture() OVERRIDE; virtual gfx::Point GetLocationOnScreen() OVERRIDE; virtual void ScrollContainerViewTo(gfx::Vector2d new_value) OVERRIDE; diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 179bd35..7bd66cd9 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -412,7 +412,8 @@ void PictureLayerImpl::UpdateTiles( // resourceless software draw, so don't update them. if (!layer_tree_impl()->resourceless_software_draw()) { visible_rect_for_tile_priority_ = visible_content_rect(); - viewport_size_for_tile_priority_ = layer_tree_impl()->DrawViewportSize(); + viewport_rect_for_tile_priority_ = + layer_tree_impl()->ViewportRectForTilePriority(); screen_space_transform_for_tile_priority_ = screen_space_transform(); } @@ -470,16 +471,22 @@ void PictureLayerImpl::UpdateTilePriorities( if (!tiling_needs_update) return; - // Use visible_content_rect, unless it's empty. If it's empty, then - // try to inverse project the viewport into layer space and use that. + // If visible_rect_for_tile_priority_ is empty or + // viewport_rect_for_tile_priority_ is set to be different from the device + // viewport, try to inverse project the viewport into layer space and use + // that. Otherwise just use visible_rect_for_tile_priority_ gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_; - if (visible_rect_in_content_space.IsEmpty()) { - gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization); - if (screen_space_transform_for_tile_priority_.GetInverse( - &screen_to_layer)) { + + if (visible_rect_in_content_space.IsEmpty() || + layer_tree_impl()->DeviceViewport() != viewport_rect_for_tile_priority_) { + gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization); + + if (screen_space_transform_for_tile_priority_.GetInverse(&view_to_layer)) { + // Transform from view space to content space. visible_rect_in_content_space = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( - screen_to_layer, gfx::Rect(viewport_size_for_tile_priority_))); + view_to_layer, viewport_rect_for_tile_priority_)); + visible_rect_in_content_space.Intersect(gfx::Rect(content_bounds())); } } diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index d492051..3a21ca1 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -214,7 +214,7 @@ class CC_EXPORT PictureLayerImpl // Save a copy of the visible rect and viewport size of the last frame that // has a valid viewport for prioritizing tiles. gfx::Rect visible_rect_for_tile_priority_; - gfx::Size viewport_size_for_tile_priority_; + gfx::Rect viewport_rect_for_tile_priority_; gfx::Transform screen_space_transform_for_tile_priority_; friend class PictureLayer; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index cdd0b92..5c23534 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -9,6 +9,7 @@ #include <set> #include <utility> +#include "cc/base/math_util.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/picture_layer.h" #include "cc/quads/draw_quad.h" @@ -302,6 +303,103 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) { VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), active_pile.get()); } +TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { + base::TimeTicks time_ticks; + host_impl_.SetCurrentFrameTimeTicks(time_ticks); + gfx::Size tile_size(100, 100); + gfx::Size layer_bounds(400, 400); + + scoped_refptr<FakePicturePileImpl> pending_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + scoped_refptr<FakePicturePileImpl> active_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + + SetupTrees(pending_pile, active_pile); + + Region invalidation; + AddDefaultTilingsWithInvalidation(invalidation); + SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false); + + // Update tiles with viewport for tile priority as (0, 0, 100, 100) and the + // identify transform for tile priority. + bool resourceless_software_draw = false; + gfx::Rect viewport = gfx::Rect(layer_bounds), + viewport_rect_for_tile_priority = gfx::Rect(0, 0, 100, 100); + gfx::Transform transform, transform_for_tile_priority; + + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport_rect_for_tile_priority, + transform_for_tile_priority, + resourceless_software_draw); + active_layer_->draw_properties().visible_content_rect = viewport; + active_layer_->draw_properties().screen_space_transform = transform; + active_layer_->UpdateTiles(NULL); + + gfx::Rect viewport_rect_for_tile_priority_in_view_space = + viewport_rect_for_tile_priority; + + // Verify the viewport rect for tile priority is used in picture layer impl. + EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(), + viewport_rect_for_tile_priority_in_view_space); + + // Verify the viewport rect for tile priority is used in picture layer tiling. + PictureLayerTilingSet* tilings = active_layer_->tilings(); + for (size_t i = 0; i < tilings->num_tilings(); i++) { + PictureLayerTiling* tiling = tilings->tiling_at(i); + EXPECT_EQ( + tiling->GetCurrentVisibleRectForTesting(), + gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, + tiling->contents_scale())); + } + + // Update tiles with viewport for tile priority as (200, 200, 100, 100) in + // screen space and the transform for tile priority is translated and + // rotated. The actual viewport for tile priority used by PictureLayerImpl + // should be (200, 200, 100, 100) applied with the said transform. + time_ticks += base::TimeDelta::FromMilliseconds(200); + host_impl_.SetCurrentFrameTimeTicks(time_ticks); + + viewport_rect_for_tile_priority = gfx::Rect(200, 200, 100, 100); + transform_for_tile_priority.Translate(100, 100); + transform_for_tile_priority.Rotate(45); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport_rect_for_tile_priority, + transform_for_tile_priority, + resourceless_software_draw); + active_layer_->draw_properties().visible_content_rect = viewport; + active_layer_->draw_properties().screen_space_transform = transform; + active_layer_->UpdateTiles(NULL); + + gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); + bool success = transform_for_tile_priority.GetInverse(&screen_to_view); + EXPECT_TRUE(success); + + viewport_rect_for_tile_priority_in_view_space = + gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( + screen_to_view, viewport_rect_for_tile_priority)); + + // Verify the viewport rect for tile priority is used in PictureLayerImpl. + EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(), + viewport_rect_for_tile_priority_in_view_space); + + // Interset viewport_rect_for_tile_priority_in_view_space with the layer + // bounds and the result should be used in PictureLayerTiling. + viewport_rect_for_tile_priority_in_view_space.Intersect( + gfx::Rect(layer_bounds)); + tilings = active_layer_->tilings(); + for (size_t i = 0; i < tilings->num_tilings(); i++) { + PictureLayerTiling* tiling = tilings->tiling_at(i); + EXPECT_EQ( + tiling->GetCurrentVisibleRectForTesting(), + gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, + tiling->contents_scale())); + } +} + TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) { base::TimeTicks time_ticks; host_impl_.SetCurrentFrameTimeTicks(time_ticks); @@ -326,8 +424,12 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) { bool resourceless_software_draw = false; gfx::Rect viewport = gfx::Rect(layer_bounds); gfx::Transform transform; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->draw_properties().visible_content_rect = viewport; active_layer_->draw_properties().screen_space_transform = transform; active_layer_->UpdateTiles(NULL); @@ -335,9 +437,9 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) { gfx::Rect visible_rect_for_tile_priority = active_layer_->visible_rect_for_tile_priority(); EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty()); - gfx::Size viewport_size_for_tile_priority = - active_layer_->viewport_size_for_tile_priority(); - EXPECT_FALSE(viewport_size_for_tile_priority.IsEmpty()); + gfx::Rect viewport_rect_for_tile_priority = + active_layer_->viewport_rect_for_tile_priority(); + EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty()); gfx::Transform screen_space_transform_for_tile_priority = active_layer_->screen_space_transform_for_tile_priority(); @@ -350,14 +452,18 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) { transform.Translate(1.f, 1.f); active_layer_->draw_properties().visible_content_rect = viewport; active_layer_->draw_properties().screen_space_transform = transform; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->UpdateTiles(NULL); EXPECT_RECT_EQ(visible_rect_for_tile_priority, active_layer_->visible_rect_for_tile_priority()); - EXPECT_SIZE_EQ(viewport_size_for_tile_priority, - active_layer_->viewport_size_for_tile_priority()); + EXPECT_RECT_EQ(viewport_rect_for_tile_priority, + active_layer_->viewport_rect_for_tile_priority()); EXPECT_TRANSFORMATION_MATRIX_EQ( screen_space_transform_for_tile_priority, active_layer_->screen_space_transform_for_tile_priority()); @@ -366,14 +472,18 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) { time_ticks += base::TimeDelta::FromMilliseconds(200); host_impl_.SetCurrentFrameTimeTicks(time_ticks); resourceless_software_draw = false; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->UpdateTiles(NULL); EXPECT_FALSE(visible_rect_for_tile_priority == active_layer_->visible_rect_for_tile_priority()); - EXPECT_FALSE(viewport_size_for_tile_priority == - active_layer_->viewport_size_for_tile_priority()); + EXPECT_FALSE(viewport_rect_for_tile_priority == + active_layer_->viewport_rect_for_tile_priority()); EXPECT_FALSE(screen_space_transform_for_tile_priority == active_layer_->screen_space_transform_for_tile_priority()); } @@ -397,8 +507,13 @@ TEST_F(PictureLayerImplTest, InvalidViewportAfterReleaseResources) { bool resourceless_software_draw = true; gfx::Rect viewport = gfx::Rect(layer_bounds); - host_impl_.SetExternalDrawConstraints( - gfx::Transform(), viewport, viewport, resourceless_software_draw); + gfx::Transform identity = gfx::Transform(); + host_impl_.SetExternalDrawConstraints(identity, + viewport, + viewport, + viewport, + identity, + resourceless_software_draw); ResetTilingsAndRasterScales(); host_impl_.pending_tree()->UpdateDrawProperties(); host_impl_.active_tree()->UpdateDrawProperties(); @@ -2577,8 +2692,12 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) { bool resourceless_software_draw = false; gfx::Rect viewport = gfx::Rect(layer_bounds); gfx::Transform transform; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->draw_properties().visible_content_rect = viewport; active_layer_->draw_properties().screen_space_transform = transform; active_layer_->UpdateTiles(NULL); @@ -2586,9 +2705,9 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) { gfx::Rect visible_rect_for_tile_priority = active_layer_->visible_rect_for_tile_priority(); EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty()); - gfx::Size viewport_size_for_tile_priority = - active_layer_->viewport_size_for_tile_priority(); - EXPECT_FALSE(viewport_size_for_tile_priority.IsEmpty()); + gfx::Rect viewport_rect_for_tile_priority = + active_layer_->viewport_rect_for_tile_priority(); + EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty()); gfx::Transform screen_space_transform_for_tile_priority = active_layer_->screen_space_transform_for_tile_priority(); @@ -2601,14 +2720,18 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) { transform.Translate(1.f, 1.f); active_layer_->draw_properties().visible_content_rect = viewport; active_layer_->draw_properties().screen_space_transform = transform; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->UpdateTiles(NULL); EXPECT_RECT_EQ(visible_rect_for_tile_priority, active_layer_->visible_rect_for_tile_priority()); - EXPECT_SIZE_EQ(viewport_size_for_tile_priority, - active_layer_->viewport_size_for_tile_priority()); + EXPECT_RECT_EQ(viewport_rect_for_tile_priority, + active_layer_->viewport_rect_for_tile_priority()); EXPECT_TRANSFORMATION_MATRIX_EQ( screen_space_transform_for_tile_priority, active_layer_->screen_space_transform_for_tile_priority()); @@ -2617,14 +2740,18 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) { time_ticks += base::TimeDelta::FromMilliseconds(200); host_impl_.SetCurrentFrameTimeTicks(time_ticks); resourceless_software_draw = false; - host_impl_.SetExternalDrawConstraints( - transform, viewport, viewport, resourceless_software_draw); + host_impl_.SetExternalDrawConstraints(transform, + viewport, + viewport, + viewport, + transform, + resourceless_software_draw); active_layer_->UpdateTiles(NULL); EXPECT_FALSE(visible_rect_for_tile_priority == active_layer_->visible_rect_for_tile_priority()); - EXPECT_FALSE(viewport_size_for_tile_priority == - active_layer_->viewport_size_for_tile_priority()); + EXPECT_FALSE(viewport_rect_for_tile_priority == + active_layer_->viewport_rect_for_tile_priority()); EXPECT_FALSE(screen_space_transform_for_tile_priority == active_layer_->screen_space_transform_for_tile_priority()); } @@ -2648,8 +2775,13 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportAfterReleaseResources) { bool resourceless_software_draw = true; gfx::Rect viewport = gfx::Rect(layer_bounds); - host_impl_.SetExternalDrawConstraints( - gfx::Transform(), viewport, viewport, resourceless_software_draw); + gfx::Transform identity = gfx::Transform(); + host_impl_.SetExternalDrawConstraints(identity, + viewport, + viewport, + viewport, + identity, + resourceless_software_draw); ResetTilingsAndRasterScales(); host_impl_.pending_tree()->UpdateDrawProperties(); host_impl_.active_tree()->UpdateDrawProperties(); diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 8283f06..a19a83e 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -93,9 +93,15 @@ void OutputSurface::SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw) { - client_->SetExternalDrawConstraints( - transform, viewport, clip, resourceless_software_draw); + client_->SetExternalDrawConstraints(transform, + viewport, + clip, + viewport_rect_for_tile_priority, + transform_for_tile_priority, + resourceless_software_draw); } OutputSurface::~OutputSurface() { diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index cec247d..f3a874a 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -161,10 +161,13 @@ class CC_EXPORT OutputSurface { void ReclaimResources(const CompositorFrameAck* ack); void DidLoseOutputSurface(); void SetExternalStencilTest(bool enabled); - void SetExternalDrawConstraints(const gfx::Transform& transform, - const gfx::Rect& viewport, - const gfx::Rect& clip, - bool resourceless_software_draw); + void SetExternalDrawConstraints( + const gfx::Transform& transform, + const gfx::Rect& viewport, + const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, + bool resourceless_software_draw); private: void SetUpContext3d(); diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index 2c6c128..bb37a91 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -38,10 +38,13 @@ class CC_EXPORT OutputSurfaceClient { virtual void DidSwapBuffersComplete() = 0; virtual void ReclaimResources(const CompositorFrameAck* ack) = 0; virtual void DidLoseOutputSurface() = 0; - virtual void SetExternalDrawConstraints(const gfx::Transform& transform, - const gfx::Rect& viewport, - const gfx::Rect& clip, - bool resourceless_software_draw) = 0; + virtual void SetExternalDrawConstraints( + const gfx::Transform& transform, + const gfx::Rect& viewport, + const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, + bool resourceless_software_draw) = 0; virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; // If set, |callback| will be called subsequent to each new tree activation, // regardless of the compositor visibility or damage. |callback| must remain diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index e0a368d..808d575 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -162,6 +162,10 @@ class CC_EXPORT PictureLayerTiling { return all_tiles; } + const gfx::Rect& GetCurrentVisibleRectForTesting() const { + return current_visible_rect_; + } + // Iterate over all tiles to fill content_rect. Even if tiles are invalid // (i.e. no valid resource) this tiling should still iterate over them. // The union of all geometry_rect calls for each element iterated over should diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 9718597..93606ba 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h @@ -61,6 +61,8 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient, const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw) OVERRIDE {} virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE {} virtual void SetTreeActivationCallback( diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h index 5e887b8..7ecb6cf 100644 --- a/cc/test/fake_output_surface_client.h +++ b/cc/test/fake_output_surface_client.h @@ -42,6 +42,8 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw) OVERRIDE {} virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {} diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h index ffbfd1e..f101b0f 100644 --- a/cc/test/fake_picture_layer_impl.h +++ b/cc/test/fake_picture_layer_impl.h @@ -79,8 +79,8 @@ class FakePictureLayerImpl : public PictureLayerImpl { gfx::Rect visible_rect_for_tile_priority() { return visible_rect_for_tile_priority_; } - gfx::Size viewport_size_for_tile_priority() { - return viewport_size_for_tile_priority_; + gfx::Rect viewport_rect_for_tile_priority() { + return viewport_rect_for_tile_priority_; } gfx::Transform screen_space_transform_for_tile_priority() { return screen_space_transform_for_tile_priority_; diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index cbb936b..4e4e039 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc @@ -76,8 +76,13 @@ void LayerTreePixelTest::CommitCompleteOnThread(LayerTreeHostImpl* impl) { // Be that influence! viewport += gfx::Vector2d(20, 10); bool resourceless_software_draw = false; - impl->SetExternalDrawConstraints( - gfx::Transform(), viewport, viewport, resourceless_software_draw); + gfx::Transform identity = gfx::Transform(); + impl->SetExternalDrawConstraints(identity, + viewport, + viewport, + viewport, + identity, + resourceless_software_draw); EXPECT_EQ(viewport.ToString(), impl->DeviceViewport().ToString()); } diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 283240d..fdf8e5c 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -69,6 +69,7 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/GLES2/gl2extchromium.h" #include "ui/gfx/frame_time.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/size_conversions.h" #include "ui/gfx/vector2d_conversions.h" @@ -1375,15 +1376,32 @@ void LayerTreeHostImpl::SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw) { + gfx::Rect viewport_rect_for_tile_priority_in_view_space; + if (!resourceless_software_draw) { + gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); + if (transform_for_tile_priority.GetInverse(&screen_to_view)) { + // Convert from screen space to view space. + viewport_rect_for_tile_priority_in_view_space = + gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( + screen_to_view, viewport_rect_for_tile_priority)); + } + } + if (external_transform_ != transform || external_viewport_ != viewport || - resourceless_software_draw_ != resourceless_software_draw) { + resourceless_software_draw_ != resourceless_software_draw || + viewport_rect_for_tile_priority_ != + viewport_rect_for_tile_priority_in_view_space) { active_tree_->set_needs_update_draw_properties(); } external_transform_ = transform; external_viewport_ = viewport; external_clip_ = clip; + viewport_rect_for_tile_priority_ = + viewport_rect_for_tile_priority_in_view_space; resourceless_software_draw_ = resourceless_software_draw; } @@ -2199,6 +2217,13 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { SetFullRootLayerDamage(); } +const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const { + if (viewport_rect_for_tile_priority_.IsEmpty()) + return DeviceViewport(); + + return viewport_rect_for_tile_priority_; +} + gfx::Size LayerTreeHostImpl::DrawViewportSize() const { return DeviceViewport().size(); } diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index eae2866..7b3c3fd 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -224,6 +224,9 @@ class CC_EXPORT LayerTreeHostImpl // for draw properties, tilings, quads and render passes. gfx::Size DrawViewportSize() const; + // Viewport rect in view space used for tiling prioritization. + const gfx::Rect ViewportRectForTilePriority() const; + // Viewport size for scrolling and fixed-position compensation. This value // excludes the URL bar and non-overlay scrollbars and is in DIP (and // invariant relative to page scale). @@ -256,10 +259,13 @@ class CC_EXPORT LayerTreeHostImpl base::TimeDelta interval) OVERRIDE; virtual void SetNeedsRedrawRect(const gfx::Rect& rect) OVERRIDE; virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; + virtual void SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw) OVERRIDE; virtual void DidLoseOutputSurface() OVERRIDE; virtual void DidSwapBuffers() OVERRIDE; @@ -668,9 +674,12 @@ class CC_EXPORT LayerTreeHostImpl // - external_viewport_ is used DrawProperties, tile management and // glViewport/window projection matrix. // - external_clip_ specifies a top-level clip rect + // - viewport_rect_for_tile_priority_ is the rect in view space used for + // tiling priority. gfx::Transform external_transform_; gfx::Rect external_viewport_; gfx::Rect external_clip_; + gfx::Rect viewport_rect_for_tile_priority_; bool resourceless_software_draw_; gfx::Rect viewport_damage_rect_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index a13c09a..05ccc45 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -5577,6 +5577,8 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, + external_viewport, + external_transform, resourceless_software_draw); EXPECT_EQ(0, software_device->frames_began_); @@ -5610,6 +5612,8 @@ TEST_F(LayerTreeHostImplTest, host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, + external_viewport, + external_transform, resourceless_software_draw); // SolidColorLayerImpl will be drawn. @@ -6654,6 +6658,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, + external_viewport, + external_transform, resourceless_software_draw); DrawFrame(); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -6663,6 +6669,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, + external_viewport, + external_transform, resourceless_software_draw); DrawFrame(); EXPECT_TRANSFORMATION_MATRIX_EQ( diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index b696769..4b21b14 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -750,10 +750,18 @@ void LayerTreeImpl::SetNeedsCommit() { layer_tree_host_impl_->SetNeedsCommit(); } +gfx::Rect LayerTreeImpl::DeviceViewport() const { + return layer_tree_host_impl_->DeviceViewport(); +} + gfx::Size LayerTreeImpl::DrawViewportSize() const { return layer_tree_host_impl_->DrawViewportSize(); } +const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const { + return layer_tree_host_impl_->ViewportRectForTilePriority(); +} + scoped_ptr<ScrollbarAnimationController> LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) { DCHECK(settings().scrollbar_fade_delay_ms); diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 89bd6c4..e602872 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h @@ -87,7 +87,9 @@ class CC_EXPORT LayerTreeImpl { base::TimeTicks CurrentFrameTimeTicks() const; base::TimeDelta begin_impl_frame_interval() const; void SetNeedsCommit(); + gfx::Rect DeviceViewport() const; gfx::Size DrawViewportSize() const; + const gfx::Rect ViewportRectForTilePriority() const; scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController( LayerImpl* scrolling_layer); void DidAnimateScrollOffset(); diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc index bb8c521..6fe045a 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc @@ -124,12 +124,19 @@ scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( gfx::Size surface_size, const gfx::Transform& transform, gfx::Rect viewport, - gfx::Rect clip) { + gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority) { DCHECK(CalledOnValidThread()); DCHECK(output_surface_); scoped_ptr<cc::CompositorFrame> frame = - output_surface_->DemandDrawHw(surface_size, transform, viewport, clip); + output_surface_->DemandDrawHw(surface_size, + transform, + viewport, + clip, + viewport_rect_for_tile_priority, + transform_for_tile_priority); if (frame.get()) UpdateFrameMetaData(frame->metadata); diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h index aac375e..7434a8b 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_impl.h @@ -58,7 +58,9 @@ class SynchronousCompositorImpl gfx::Size surface_size, const gfx::Transform& transform, gfx::Rect viewport, - gfx::Rect clip) OVERRIDE; + gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority) OVERRIDE; virtual bool DemandDrawSw(SkCanvas* canvas) OVERRIDE; virtual void ReturnResources( const cc::CompositorFrameAck& frame_ack) OVERRIDE; diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc index 6701965..682c530 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc @@ -165,13 +165,20 @@ SynchronousCompositorOutputSurface::DemandDrawHw( gfx::Size surface_size, const gfx::Transform& transform, gfx::Rect viewport, - gfx::Rect clip) { + gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority) { DCHECK(CalledOnValidThread()); DCHECK(HasClient()); DCHECK(context_provider_); surface_size_ = surface_size; - InvokeComposite(transform, viewport, clip, true); + InvokeComposite(transform, + viewport, + clip, + viewport_rect_for_tile_priority, + transform_for_tile_priority, + true); return frame_holder_.Pass(); } @@ -193,7 +200,9 @@ SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { surface_size_ = gfx::Size(canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); - InvokeComposite(transform, clip, clip, false); + // Resourceless software draw does not need viewport_for_tiling. + gfx::Rect empty; + InvokeComposite(transform, clip, clip, empty, gfx::Transform(), false); return frame_holder_.Pass(); } @@ -202,6 +211,8 @@ void SynchronousCompositorOutputSurface::InvokeComposite( const gfx::Transform& transform, gfx::Rect viewport, gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + gfx::Transform transform_for_tile_priority, bool hardware_draw) { DCHECK(!invoking_composite_); DCHECK(!frame_holder_.get()); @@ -209,8 +220,12 @@ void SynchronousCompositorOutputSurface::InvokeComposite( gfx::Transform adjusted_transform = transform; AdjustTransform(&adjusted_transform, viewport); - SetExternalDrawConstraints( - adjusted_transform, viewport, clip, !hardware_draw); + SetExternalDrawConstraints(adjusted_transform, + viewport, + clip, + viewport_rect_for_tile_priority, + transform_for_tile_priority, + !hardware_draw); SetNeedsRedrawRect(gfx::Rect(viewport.size())); client_->BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor()); @@ -221,11 +236,16 @@ void SynchronousCompositorOutputSurface::InvokeComposite( cached_hw_transform_ = adjusted_transform; cached_hw_viewport_ = viewport; cached_hw_clip_ = clip; + cached_hw_viewport_rect_for_tile_priority_ = + viewport_rect_for_tile_priority; + cached_hw_transform_for_tile_priority_ = transform_for_tile_priority; } else { bool resourceless_software_draw = false; SetExternalDrawConstraints(cached_hw_transform_, cached_hw_viewport_, cached_hw_clip_, + cached_hw_viewport_rect_for_tile_priority_, + cached_hw_transform_for_tile_priority_, resourceless_software_draw); } diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h index ab9cd42..d24f333 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.h +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h @@ -74,10 +74,13 @@ class SynchronousCompositorOutputSurface bool InitializeHwDraw( scoped_refptr<cc::ContextProvider> onscreen_context_provider); void ReleaseHwDraw(); - scoped_ptr<cc::CompositorFrame> DemandDrawHw(gfx::Size surface_size, - const gfx::Transform& transform, - gfx::Rect viewport, - gfx::Rect clip); + scoped_ptr<cc::CompositorFrame> DemandDrawHw( + gfx::Size surface_size, + const gfx::Transform& transform, + gfx::Rect viewport, + gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority); void ReturnResources(const cc::CompositorFrameAck& frame_ack); scoped_ptr<cc::CompositorFrame> DemandDrawSw(SkCanvas* canvas); void SetMemoryPolicy(const SynchronousCompositorMemoryPolicy& policy); @@ -90,6 +93,8 @@ class SynchronousCompositorOutputSurface void InvokeComposite(const gfx::Transform& transform, gfx::Rect viewport, gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + gfx::Transform transform_for_tile_priority, bool hardware_draw); bool CalledOnValidThread() const; SynchronousCompositorOutputSurfaceDelegate* GetDelegate(); @@ -101,6 +106,8 @@ class SynchronousCompositorOutputSurface gfx::Transform cached_hw_transform_; gfx::Rect cached_hw_viewport_; gfx::Rect cached_hw_clip_; + gfx::Rect cached_hw_viewport_rect_for_tile_priority_; + gfx::Transform cached_hw_transform_for_tile_priority_; // Only valid (non-NULL) during a DemandDrawSw() call. SkCanvas* current_sw_canvas_; diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h index 62485f1..72c2b19 100644 --- a/content/public/browser/android/synchronous_compositor.h +++ b/content/public/browser/android/synchronous_compositor.h @@ -91,7 +91,9 @@ class CONTENT_EXPORT SynchronousCompositor { gfx::Size surface_size, const gfx::Transform& transform, gfx::Rect viewport, - gfx::Rect clip) = 0; + gfx::Rect clip, + gfx::Rect viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority) = 0; // For delegated rendering, return resources from parent compositor to this. // Note that all resources must be returned before ReleaseHwDraw. |