Commit 785b0af2 authored by danakj@chromium.org's avatar danakj@chromium.org

aura: Use Layer::SetShowPaintedContent to stop showing external content

Currently we use SetExternalTexture(NULL) or SetDelegatedFrame(NULL)
to switch back to showing painted content. This is kinda indirect,
and won't play nicely when SetExternalTexture() is removed, and when
we use a FrameProvider for delegated frames instead of pushing them
to the ui::Layer directly one at a time.

Instead, add SetShowPaintedContent() to switch to a content layer,
and disallow setting a NULL/empty texture or delegated frame.

Also View::SetExternalTexture() is not used, remove it so it doesn't
have to think about this change.

R=piman,sadrul
BUG=263069

Review URL: https://codereview.chromium.org/25596002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226502 0039d316-1c4b-4281-b951-d872f2087c98
parent 2849dd08
......@@ -98,7 +98,7 @@ void ReflectorImpl::OnMirroringCompositorResized() {
void ReflectorImpl::OnLostResources() {
shared_texture_ = NULL;
mirroring_layer_->SetExternalTexture(NULL);
mirroring_layer_->SetShowPaintedContent();
}
void ReflectorImpl::OnReshape(gfx::Size size) {
......
......@@ -1299,7 +1299,7 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
mailbox.shared_memory_size());
CheckResizeLock();
} else {
window_->layer()->SetExternalTexture(NULL);
window_->layer()->SetShowPaintedContent();
resize_lock_.reset();
host_->WasResized();
framebuffer_holder_ = NULL;
......@@ -1430,7 +1430,8 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
gfx::Rect damage_rect;
gfx::Rect damage_rect_in_dip;
if (!frame_data->render_pass_list.empty()) {
bool has_content = !frame_data->render_pass_list.empty();
if (has_content) {
cc::RenderPass* root_pass = frame_data->render_pass_list.back();
frame_size = root_pass->output_rect.size();
......@@ -1472,12 +1473,15 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
// indicates the renderer's output surface may have been recreated, in which
// case we should recreate the DelegatedRendererLayer, to avoid matching
// resources from the old one with resources from the new one which would
// have the same id.
window_->layer()->SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData>(),
frame_size_in_dip);
// have the same id. Changing the layer to showing painted content destroys
// the DelegatedRendererLayer.
window_->layer()->SetShowPaintedContent();
last_output_surface_id_ = output_surface_id;
}
window_->layer()->SetDelegatedFrame(frame_data.Pass(), frame_size_in_dip);
if (has_content)
window_->layer()->SetDelegatedFrame(frame_data.Pass(), frame_size_in_dip);
else
window_->layer()->SetShowPaintedContent();
released_front_lock_ = NULL;
current_frame_size_ = frame_size_in_dip;
CheckResizeLock();
......@@ -2592,8 +2596,11 @@ void RenderWidgetHostViewAura::DidRecreateLayer(ui::Layer *old_layer,
current_surface_->device_scale_factor(), texture_id);
}
}
old_layer->SetExternalTexture(new_texture);
new_layer->SetExternalTexture(old_texture);
if (new_texture.get())
old_layer->SetExternalTexture(new_texture.get());
else
old_layer->SetShowPaintedContent();
new_layer->SetExternalTexture(old_texture.get());
} else if (old_mailbox.IsSharedMemory()) {
base::SharedMemory* old_buffer = old_mailbox.shared_memory();
const size_t size = old_mailbox.shared_memory_size_in_bytes();
......@@ -3348,9 +3355,10 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() {
ui::Compositor* compositor = GetCompositor();
// We can't get notification for commits after this point, which would
// guarantee that the compositor isn't using an old texture any more, so
// instead we force the texture to NULL which synchronizes with the compositor
// thread, and makes it safe to run the callback.
window_->layer()->SetExternalTexture(NULL);
// instead we force the layer to stop using any external resources which
// synchronizes with the compositor thread, and makes it safe to run the
// callback.
window_->layer()->SetShowPaintedContent();
RunOnCommitCallbacks();
resize_lock_.reset();
host_->WasResized();
......
......@@ -227,7 +227,7 @@ class WebGLBench : public BenchCompositorObserver {
virtual ~WebGLBench() {
context_provider_->Context3d()->makeContextCurrent();
context_provider_->Context3d()->deleteFramebuffer(fbo_);
webgl_.SetExternalTexture(NULL);
webgl_.SetShowPaintedContent();
texture_ = NULL;
compositor_->RemoveObserver(this);
}
......
......@@ -476,30 +476,21 @@ void Layer::SwitchCCLayerForTest() {
}
void Layer::SetExternalTexture(Texture* texture) {
DCHECK(texture);
// Hold a ref to the old |Texture| until we have updated all
// compositor references to the texture id that it holds.
scoped_refptr<ui::Texture> old_texture = texture_;
DCHECK_EQ(type_, LAYER_TEXTURED);
DCHECK(!solid_color_layer_.get());
bool has_texture = !!texture;
layer_updated_externally_ = has_texture;
layer_updated_externally_ = true;
texture_ = texture;
if (!!texture_layer_.get() != has_texture) {
// Switch to a different type of layer.
if (has_texture) {
scoped_refptr<cc::TextureLayer> new_layer =
cc::TextureLayer::Create(this);
new_layer->SetFlipped(texture_->flipped());
SwitchToLayer(new_layer);
texture_layer_ = new_layer;
} else {
scoped_refptr<cc::ContentLayer> new_layer =
cc::ContentLayer::Create(this);
SwitchToLayer(new_layer);
content_layer_ = new_layer;
mailbox_ = cc::TextureMailbox();
}
if (!texture_layer_.get()) {
scoped_refptr<cc::TextureLayer> new_layer = cc::TextureLayer::Create(this);
new_layer->SetFlipped(texture_->flipped());
SwitchToLayer(new_layer);
texture_layer_ = new_layer;
}
RecomputeDrawsContentAndUVRect();
}
......@@ -533,25 +524,18 @@ cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) {
void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame,
gfx::Size frame_size_in_dip) {
DCHECK(frame && !frame->render_pass_list.empty());
DCHECK_EQ(type_, LAYER_TEXTURED);
bool has_frame = frame.get() && !frame->render_pass_list.empty();
layer_updated_externally_ = has_frame;
layer_updated_externally_ = true;
delegated_frame_size_in_dip_ = frame_size_in_dip;
if (!!delegated_renderer_layer_.get() != has_frame) {
if (has_frame) {
scoped_refptr<cc::DelegatedRendererLayer> new_layer =
cc::DelegatedRendererLayer::Create(NULL);
SwitchToLayer(new_layer);
delegated_renderer_layer_ = new_layer;
} else {
scoped_refptr<cc::ContentLayer> new_layer =
cc::ContentLayer::Create(this);
SwitchToLayer(new_layer);
content_layer_ = new_layer;
}
if (!delegated_renderer_layer_.get()) {
scoped_refptr<cc::DelegatedRendererLayer> new_layer =
cc::DelegatedRendererLayer::Create(NULL);
SwitchToLayer(new_layer);
delegated_renderer_layer_ = new_layer;
}
if (has_frame)
delegated_renderer_layer_->SetFrameData(frame.Pass());
delegated_renderer_layer_->SetFrameData(frame.Pass());
RecomputeDrawsContentAndUVRect();
}
......@@ -561,10 +545,23 @@ void Layer::TakeUnusedResourcesForChildCompositor(
delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list);
}
void Layer::SetColor(SkColor color) {
GetAnimator()->SetColor(color);
void Layer::SetShowPaintedContent() {
if (content_layer_.get())
return;
scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this);
SwitchToLayer(new_layer);
content_layer_ = new_layer;
layer_updated_externally_ = false;
mailbox_ = cc::TextureMailbox();
texture_ = NULL;
RecomputeDrawsContentAndUVRect();
}
void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_.get()))
return false;
......
......@@ -273,6 +273,8 @@ class COMPOSITOR_EXPORT Layer
void TakeUnusedResourcesForChildCompositor(
cc::ReturnedResourceArray* array);
void SetShowPaintedContent();
// Sets the layer's fill color. May only be called for LAYER_SOLID_COLOR.
void SetColor(SkColor color);
......
......@@ -1344,6 +1344,33 @@ TEST_F(LayerWithDelegateTest, DelegatedLayer) {
gfx::Size(20, 20).ToString());
}
TEST_F(LayerWithDelegateTest, ExternalContent) {
scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
child->SetBounds(gfx::Rect(0, 0, 10, 10));
child->SetVisible(true);
root->Add(child.get());
// The layer is already showing painted content, so the cc layer won't change.
scoped_refptr<cc::Layer> before = child->cc_layer();
child->SetShowPaintedContent();
EXPECT_TRUE(child->cc_layer());
EXPECT_EQ(before, child->cc_layer());
// Showing delegated content changes the underlying cc layer.
before = child->cc_layer();
child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10));
EXPECT_TRUE(child->cc_layer());
EXPECT_NE(before, child->cc_layer());
// Changing to painted content should change the underlying cc layer.
before = child->cc_layer();
child->SetShowPaintedContent();
EXPECT_TRUE(child->cc_layer());
EXPECT_NE(before, child->cc_layer());
}
// Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
......
......@@ -1341,21 +1341,6 @@ void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
}
bool View::SetExternalTexture(ui::Texture* texture) {
DCHECK(texture);
SetPaintToLayer(true);
layer()->SetExternalTexture(texture);
// Child views must not paint into the external texture. So make sure each
// child view has its own layer to paint into.
for (Views::iterator i = children_.begin(); i != children_.end(); ++i)
(*i)->SetPaintToLayer(true);
SchedulePaintInRect(GetLocalBounds());
return true;
}
gfx::Vector2d View::CalculateOffsetToAncestorWithLayer(
ui::Layer** layer_parent) {
if (layer()) {
......
......@@ -1066,15 +1066,6 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Accelerated painting ------------------------------------------------------
// This creates a layer for the view, if one does not exist. It then
// passes the texture to a layer associated with the view. While an external
// texture is set, the view will not update the layer contents.
//
// |texture| cannot be NULL.
//
// Returns false if it cannot create a layer to which to assign the texture.
bool SetExternalTexture(ui::Texture* texture);
// Returns the offset from this view to the nearest ancestor with a layer. If
// |layer_parent| is non-NULL it is set to the nearest ancestor with a layer.
virtual gfx::Vector2d CalculateOffsetToAncestorWithLayer(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment