OLD | NEW |
| (Empty) |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/texture_layer_impl.h" | |
6 | |
7 #include "base/stringprintf.h" | |
8 #include "cc/output/renderer.h" | |
9 #include "cc/quad_sink.h" | |
10 #include "cc/quads/texture_draw_quad.h" | |
11 #include "cc/trees/layer_tree_impl.h" | |
12 | |
13 namespace cc { | |
14 | |
15 TextureLayerImpl::TextureLayerImpl(LayerTreeImpl* tree_impl, | |
16 int id, | |
17 bool uses_mailbox) | |
18 : LayerImpl(tree_impl, id), | |
19 texture_id_(0), | |
20 external_texture_resource_(0), | |
21 premultiplied_alpha_(true), | |
22 flipped_(true), | |
23 uv_top_left_(0.f, 0.f), | |
24 uv_bottom_right_(1.f, 1.f), | |
25 uses_mailbox_(uses_mailbox), | |
26 own_mailbox_(false) { | |
27 vertex_opacity_[0] = 1.0f; | |
28 vertex_opacity_[1] = 1.0f; | |
29 vertex_opacity_[2] = 1.0f; | |
30 vertex_opacity_[3] = 1.0f; | |
31 } | |
32 | |
33 TextureLayerImpl::~TextureLayerImpl() { FreeTextureMailbox(); } | |
34 | |
35 void TextureLayerImpl::SetTextureMailbox(const TextureMailbox& mailbox) { | |
36 DCHECK(uses_mailbox_); | |
37 DCHECK(mailbox.IsEmpty() || !mailbox.Equals(texture_mailbox_)); | |
38 FreeTextureMailbox(); | |
39 texture_mailbox_ = mailbox; | |
40 own_mailbox_ = true; | |
41 } | |
42 | |
43 scoped_ptr<LayerImpl> TextureLayerImpl::CreateLayerImpl( | |
44 LayerTreeImpl* tree_impl) { | |
45 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_). | |
46 PassAs<LayerImpl>(); | |
47 } | |
48 | |
49 void TextureLayerImpl::PushPropertiesTo(LayerImpl* layer) { | |
50 LayerImpl::PushPropertiesTo(layer); | |
51 | |
52 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); | |
53 texture_layer->set_flipped(flipped_); | |
54 texture_layer->set_uv_top_left(uv_top_left_); | |
55 texture_layer->set_uv_bottom_right(uv_bottom_right_); | |
56 texture_layer->set_vertex_opacity(vertex_opacity_); | |
57 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); | |
58 if (uses_mailbox_ && own_mailbox_) { | |
59 texture_layer->SetTextureMailbox(texture_mailbox_); | |
60 own_mailbox_ = false; | |
61 } else { | |
62 texture_layer->set_texture_id(texture_id_); | |
63 } | |
64 } | |
65 | |
66 void TextureLayerImpl::WillDraw(ResourceProvider* resource_provider) { | |
67 if (uses_mailbox_ || !texture_id_) | |
68 return; | |
69 DCHECK(!external_texture_resource_); | |
70 external_texture_resource_ = | |
71 resource_provider->CreateResourceFromExternalTexture(texture_id_); | |
72 } | |
73 | |
74 void TextureLayerImpl::AppendQuads(QuadSink* quad_sink, | |
75 AppendQuadsData* append_quads_data) { | |
76 if (!external_texture_resource_) | |
77 return; | |
78 | |
79 SharedQuadState* shared_quad_state = | |
80 quad_sink->UseSharedQuadState(CreateSharedQuadState()); | |
81 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data); | |
82 | |
83 gfx::Rect quad_rect(content_bounds()); | |
84 gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); | |
85 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); | |
86 quad->SetNew(shared_quad_state, | |
87 quad_rect, | |
88 opaque_rect, | |
89 external_texture_resource_, | |
90 premultiplied_alpha_, | |
91 uv_top_left_, | |
92 uv_bottom_right_, | |
93 vertex_opacity_, | |
94 flipped_); | |
95 | |
96 // Perform explicit clipping on a quad to avoid setting a scissor later. | |
97 if (shared_quad_state->is_clipped && quad->PerformClipping()) | |
98 shared_quad_state->is_clipped = false; | |
99 if (!quad->rect.IsEmpty()) | |
100 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
101 } | |
102 | |
103 void TextureLayerImpl::DidDraw(ResourceProvider* resource_provider) { | |
104 if (uses_mailbox_ || !external_texture_resource_) | |
105 return; | |
106 // FIXME: the following assert will not be true when sending resources to a | |
107 // parent compositor. A synchronization scheme (double-buffering or | |
108 // pipelining of updates) for the client will need to exist to solve this. | |
109 DCHECK(!resource_provider->InUseByConsumer(external_texture_resource_)); | |
110 resource_provider->DeleteResource(external_texture_resource_); | |
111 external_texture_resource_ = 0; | |
112 } | |
113 | |
114 void TextureLayerImpl::DumpLayerProperties(std::string* str, int indent) const { | |
115 str->append(IndentString(indent)); | |
116 base::StringAppendF(str, | |
117 "texture layer texture id: %u premultiplied: %d\n", | |
118 texture_id_, | |
119 premultiplied_alpha_); | |
120 LayerImpl::DumpLayerProperties(str, indent); | |
121 } | |
122 | |
123 void TextureLayerImpl::DidLoseOutputSurface() { | |
124 texture_id_ = 0; | |
125 external_texture_resource_ = 0; | |
126 } | |
127 | |
128 const char* TextureLayerImpl::LayerTypeAsString() const { | |
129 return "TextureLayer"; | |
130 } | |
131 | |
132 bool TextureLayerImpl::CanClipSelf() const { | |
133 return true; | |
134 } | |
135 | |
136 void TextureLayerImpl::DidBecomeActive() { | |
137 if (!own_mailbox_) | |
138 return; | |
139 DCHECK(!external_texture_resource_); | |
140 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); | |
141 if (!texture_mailbox_.IsEmpty()) { | |
142 external_texture_resource_ = | |
143 resource_provider->CreateResourceFromTextureMailbox(texture_mailbox_); | |
144 } | |
145 own_mailbox_ = false; | |
146 } | |
147 | |
148 void TextureLayerImpl::FreeTextureMailbox() { | |
149 if (!uses_mailbox_) | |
150 return; | |
151 if (own_mailbox_) { | |
152 DCHECK(!external_texture_resource_); | |
153 texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point()); | |
154 } else if (external_texture_resource_) { | |
155 DCHECK(!own_mailbox_); | |
156 ResourceProvider* resource_provider = | |
157 layer_tree_impl()->resource_provider(); | |
158 resource_provider->DeleteResource(external_texture_resource_); | |
159 external_texture_resource_ = 0; | |
160 } | |
161 } | |
162 | |
163 } // namespace cc | |
OLD | NEW |