OLD | NEW |
| (Empty) |
1 // Copyright 2010 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.h" | |
6 | |
7 #include "cc/base/thread.h" | |
8 #include "cc/texture_layer_client.h" | |
9 #include "cc/texture_layer_impl.h" | |
10 #include "cc/trees/layer_tree_host.h" | |
11 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3
D.h" | |
12 | |
13 namespace cc { | |
14 | |
15 static void RunCallbackOnMainThread( | |
16 const TextureMailbox::ReleaseCallback& callback, | |
17 unsigned sync_point) { | |
18 callback.Run(sync_point); | |
19 } | |
20 | |
21 static void PostCallbackToMainThread( | |
22 Thread* main_thread, | |
23 const TextureMailbox::ReleaseCallback& callback, | |
24 unsigned sync_point) { | |
25 main_thread->PostTask( | |
26 base::Bind(&RunCallbackOnMainThread, callback, sync_point)); | |
27 } | |
28 | |
29 scoped_refptr<TextureLayer> TextureLayer::Create(TextureLayerClient* client) { | |
30 return scoped_refptr<TextureLayer>(new TextureLayer(client, false)); | |
31 } | |
32 | |
33 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox() { | |
34 return scoped_refptr<TextureLayer>(new TextureLayer(NULL, true)); | |
35 } | |
36 | |
37 TextureLayer::TextureLayer(TextureLayerClient* client, bool uses_mailbox) | |
38 : Layer(), | |
39 client_(client), | |
40 uses_mailbox_(uses_mailbox), | |
41 flipped_(true), | |
42 uv_top_left_(0.f, 0.f), | |
43 uv_bottom_right_(1.f, 1.f), | |
44 premultiplied_alpha_(true), | |
45 rate_limit_context_(false), | |
46 context_lost_(false), | |
47 texture_id_(0), | |
48 content_committed_(false), | |
49 own_mailbox_(false) { | |
50 vertex_opacity_[0] = 1.0f; | |
51 vertex_opacity_[1] = 1.0f; | |
52 vertex_opacity_[2] = 1.0f; | |
53 vertex_opacity_[3] = 1.0f; | |
54 } | |
55 | |
56 TextureLayer::~TextureLayer() { | |
57 if (layer_tree_host()) { | |
58 if (texture_id_) | |
59 layer_tree_host()->AcquireLayerTextures(); | |
60 if (rate_limit_context_ && client_) | |
61 layer_tree_host()->StopRateLimiter(client_->context()); | |
62 } | |
63 if (own_mailbox_) | |
64 texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point()); | |
65 } | |
66 | |
67 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { | |
68 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_). | |
69 PassAs<LayerImpl>(); | |
70 } | |
71 | |
72 void TextureLayer::SetFlipped(bool flipped) { | |
73 flipped_ = flipped; | |
74 SetNeedsCommit(); | |
75 } | |
76 | |
77 void TextureLayer::SetUV(gfx::PointF top_left, gfx::PointF bottom_right) { | |
78 uv_top_left_ = top_left; | |
79 uv_bottom_right_ = bottom_right; | |
80 SetNeedsCommit(); | |
81 } | |
82 | |
83 void TextureLayer::SetVertexOpacity(float bottom_left, | |
84 float top_left, | |
85 float top_right, | |
86 float bottom_right) { | |
87 // Indexing according to the quad vertex generation: | |
88 // 1--2 | |
89 // | | | |
90 // 0--3 | |
91 vertex_opacity_[0] = bottom_left; | |
92 vertex_opacity_[1] = top_left; | |
93 vertex_opacity_[2] = top_right; | |
94 vertex_opacity_[3] = bottom_right; | |
95 SetNeedsCommit(); | |
96 } | |
97 | |
98 void TextureLayer::SetPremultipliedAlpha(bool premultiplied_alpha) { | |
99 premultiplied_alpha_ = premultiplied_alpha; | |
100 SetNeedsCommit(); | |
101 } | |
102 | |
103 void TextureLayer::SetRateLimitContext(bool rate_limit) { | |
104 if (!rate_limit && rate_limit_context_ && client_ && layer_tree_host()) | |
105 layer_tree_host()->StopRateLimiter(client_->context()); | |
106 | |
107 rate_limit_context_ = rate_limit; | |
108 } | |
109 | |
110 void TextureLayer::SetTextureId(unsigned id) { | |
111 DCHECK(!uses_mailbox_); | |
112 if (texture_id_ == id) | |
113 return; | |
114 if (texture_id_ && layer_tree_host()) | |
115 layer_tree_host()->AcquireLayerTextures(); | |
116 texture_id_ = id; | |
117 SetNeedsCommit(); | |
118 } | |
119 | |
120 void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox) { | |
121 DCHECK(uses_mailbox_); | |
122 DCHECK(mailbox.IsEmpty() || !mailbox.Equals(texture_mailbox_)); | |
123 // If we never commited the mailbox, we need to release it here | |
124 if (own_mailbox_) | |
125 texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point()); | |
126 texture_mailbox_ = mailbox; | |
127 own_mailbox_ = true; | |
128 | |
129 SetNeedsCommit(); | |
130 } | |
131 | |
132 void TextureLayer::WillModifyTexture() { | |
133 if (layer_tree_host() && (DrawsContent() || content_committed_)) { | |
134 layer_tree_host()->AcquireLayerTextures(); | |
135 content_committed_ = false; | |
136 } | |
137 } | |
138 | |
139 void TextureLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) { | |
140 Layer::SetNeedsDisplayRect(dirty_rect); | |
141 | |
142 if (rate_limit_context_ && client_ && layer_tree_host() && DrawsContent()) | |
143 layer_tree_host()->StartRateLimiter(client_->context()); | |
144 } | |
145 | |
146 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) { | |
147 if (texture_id_ && layer_tree_host() && host != layer_tree_host()) | |
148 layer_tree_host()->AcquireLayerTextures(); | |
149 Layer::SetLayerTreeHost(host); | |
150 } | |
151 | |
152 bool TextureLayer::DrawsContent() const { | |
153 return (client_ || texture_id_ || !texture_mailbox_.IsEmpty()) && | |
154 !context_lost_ && Layer::DrawsContent(); | |
155 } | |
156 | |
157 void TextureLayer::Update(ResourceUpdateQueue* queue, | |
158 const OcclusionTracker* occlusion, | |
159 RenderingStats* stats) { | |
160 if (client_) { | |
161 texture_id_ = client_->prepareTexture(*queue); | |
162 context_lost_ = | |
163 client_->context()->getGraphicsResetStatusARB() != GL_NO_ERROR; | |
164 } | |
165 | |
166 needs_display_ = false; | |
167 } | |
168 | |
169 void TextureLayer::PushPropertiesTo(LayerImpl* layer) { | |
170 Layer::PushPropertiesTo(layer); | |
171 | |
172 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); | |
173 texture_layer->set_flipped(flipped_); | |
174 texture_layer->set_uv_top_left(uv_top_left_); | |
175 texture_layer->set_uv_bottom_right(uv_bottom_right_); | |
176 texture_layer->set_vertex_opacity(vertex_opacity_); | |
177 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); | |
178 if (uses_mailbox_ && own_mailbox_) { | |
179 Thread* main_thread = layer_tree_host()->proxy()->MainThread(); | |
180 TextureMailbox::ReleaseCallback callback; | |
181 if (!texture_mailbox_.IsEmpty()) | |
182 callback = base::Bind( | |
183 &PostCallbackToMainThread, main_thread, texture_mailbox_.callback()); | |
184 texture_layer->SetTextureMailbox(TextureMailbox( | |
185 texture_mailbox_.name(), callback, texture_mailbox_.sync_point())); | |
186 own_mailbox_ = false; | |
187 } else { | |
188 texture_layer->set_texture_id(texture_id_); | |
189 } | |
190 content_committed_ = DrawsContent(); | |
191 } | |
192 | |
193 bool TextureLayer::BlocksPendingCommit() const { | |
194 // Double-buffered texture layers need to be blocked until they can be made | |
195 // triple-buffered. Single-buffered layers already prevent draws, so | |
196 // can block too for simplicity. | |
197 return DrawsContent(); | |
198 } | |
199 | |
200 bool TextureLayer::CanClipSelf() const { | |
201 return true; | |
202 } | |
203 | |
204 } // namespace cc | |
OLD | NEW |