OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/output/direct_renderer.h" | 5 #include "cc/output/direct_renderer.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 DirectRenderer::DrawingFrame::~DrawingFrame() {} | 61 DirectRenderer::DrawingFrame::~DrawingFrame() {} |
62 | 62 |
63 // | 63 // |
64 // static | 64 // static |
65 gfx::RectF DirectRenderer::QuadVertexRect() { | 65 gfx::RectF DirectRenderer::QuadVertexRect() { |
66 return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f); | 66 return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f); |
67 } | 67 } |
68 | 68 |
69 // static | 69 // static |
70 void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform, | 70 void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform, |
71 const gfx::Transform& quadTransform, | 71 const gfx::Transform& quad_transform, |
72 const gfx::RectF& quadRect) { | 72 const gfx::RectF& quad_rect) { |
73 *quad_rect_transform = quadTransform; | 73 *quad_rect_transform = quad_transform; |
74 quad_rect_transform->Translate(0.5 * quadRect.width() + quadRect.x(), | 74 quad_rect_transform->Translate(0.5 * quad_rect.width() + quad_rect.x(), |
75 0.5 * quadRect.height() + quadRect.y()); | 75 0.5 * quad_rect.height() + quad_rect.y()); |
76 quad_rect_transform->Scale(quadRect.width(), quadRect.height()); | 76 quad_rect_transform->Scale(quad_rect.width(), quad_rect.height()); |
77 } | 77 } |
78 | 78 |
79 // static | 79 // static |
80 void DirectRenderer::InitializeMatrices(DrawingFrame& frame, | 80 void DirectRenderer::InitializeMatrices(DrawingFrame& frame, |
81 gfx::Rect draw_rect, | 81 gfx::Rect draw_rect, |
82 bool flip_y) { | 82 bool flip_y) { |
83 if (flip_y) { | 83 if (flip_y) { |
84 frame.projection_matrix = OrthoProjectionMatrix(draw_rect.x(), | 84 frame.projection_matrix = OrthoProjectionMatrix(draw_rect.x(), |
85 draw_rect.right(), | 85 draw_rect.right(), |
86 draw_rect.bottom(), | 86 draw_rect.bottom(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 DirectRenderer::~DirectRenderer() {} | 125 DirectRenderer::~DirectRenderer() {} |
126 | 126 |
127 void DirectRenderer::SetEnlargePassTextureAmountForTesting( | 127 void DirectRenderer::SetEnlargePassTextureAmountForTesting( |
128 gfx::Vector2d amount) { | 128 gfx::Vector2d amount) { |
129 enlarge_pass_texture_amount_ = amount; | 129 enlarge_pass_texture_amount_ = amount; |
130 } | 130 } |
131 | 131 |
132 void DirectRenderer::DecideRenderPassAllocationsForFrame( | 132 void DirectRenderer::DecideRenderPassAllocationsForFrame( |
133 const RenderPassList& render_passes_in_draw_order) { | 133 const RenderPassList& render_passes_in_draw_order) { |
134 base::hash_map<RenderPass::Id, const RenderPass*> renderPassesInFrame; | 134 base::hash_map<RenderPass::Id, const RenderPass*> render_passes_in_frame; |
135 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) | 135 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) |
136 renderPassesInFrame.insert(std::pair<RenderPass::Id, const RenderPass*>( | 136 render_passes_in_frame.insert(std::pair<RenderPass::Id, const RenderPass*>( |
137 render_passes_in_draw_order[i]->id, render_passes_in_draw_order[i])); | 137 render_passes_in_draw_order[i]->id, render_passes_in_draw_order[i])); |
138 | 138 |
139 std::vector<RenderPass::Id> passes_to_delete; | 139 std::vector<RenderPass::Id> passes_to_delete; |
140 ScopedPtrHashMap<RenderPass::Id, CachedResource>::const_iterator passIterator; | 140 ScopedPtrHashMap<RenderPass::Id, CachedResource>::const_iterator pass_iter; |
141 for (passIterator = render_pass_textures_.begin(); | 141 for (pass_iter = render_pass_textures_.begin(); |
142 passIterator != render_pass_textures_.end(); | 142 pass_iter != render_pass_textures_.end(); |
143 ++passIterator) { | 143 ++pass_iter) { |
144 base::hash_map<RenderPass::Id, const RenderPass*>::const_iterator it = | 144 base::hash_map<RenderPass::Id, const RenderPass*>::const_iterator it = |
145 renderPassesInFrame.find(passIterator->first); | 145 render_passes_in_frame.find(pass_iter->first); |
146 if (it == renderPassesInFrame.end()) { | 146 if (it == render_passes_in_frame.end()) { |
147 passes_to_delete.push_back(passIterator->first); | 147 passes_to_delete.push_back(pass_iter->first); |
148 continue; | 148 continue; |
149 } | 149 } |
150 | 150 |
151 const RenderPass* render_pass_in_frame = it->second; | 151 const RenderPass* render_pass_in_frame = it->second; |
152 gfx::Size required_size = RenderPassTextureSize(render_pass_in_frame); | 152 gfx::Size required_size = RenderPassTextureSize(render_pass_in_frame); |
153 GLenum required_format = RenderPassTextureFormat(render_pass_in_frame); | 153 GLenum required_format = RenderPassTextureFormat(render_pass_in_frame); |
154 CachedResource* texture = passIterator->second; | 154 CachedResource* texture = pass_iter->second; |
155 DCHECK(texture); | 155 DCHECK(texture); |
156 | 156 |
157 bool size_appropriate = texture->size().width() >= required_size.width() && | 157 bool size_appropriate = texture->size().width() >= required_size.width() && |
158 texture->size().height() >= required_size.height(); | 158 texture->size().height() >= required_size.height(); |
159 if (texture->id() && | 159 if (texture->id() && |
160 (!size_appropriate || texture->format() != required_format)) | 160 (!size_appropriate || texture->format() != required_format)) |
161 texture->Free(); | 161 texture->Free(); |
162 } | 162 } |
163 | 163 |
164 // Delete RenderPass textures from the previous frame that will not be used | 164 // Delete RenderPass textures from the previous frame that will not be used |
165 // again. | 165 // again. |
166 for (size_t i = 0; i < passes_to_delete.size(); ++i) | 166 for (size_t i = 0; i < passes_to_delete.size(); ++i) |
167 render_pass_textures_.erase(passes_to_delete[i]); | 167 render_pass_textures_.erase(passes_to_delete[i]); |
168 | 168 |
169 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) { | 169 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) { |
170 if (!render_pass_textures_.contains(render_passes_in_draw_order[i]->id)) { | 170 if (!render_pass_textures_.contains(render_passes_in_draw_order[i]->id)) { |
171 scoped_ptr<CachedResource> texture = | 171 scoped_ptr<CachedResource> texture = |
172 CachedResource::Create(resource_provider_); | 172 CachedResource::Create(resource_provider_); |
173 render_pass_textures_.set(render_passes_in_draw_order[i]->id, | 173 render_pass_textures_.set(render_passes_in_draw_order[i]->id, |
174 texture.Pass()); | 174 texture.Pass()); |
175 } | 175 } |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 void DirectRenderer::DrawFrame(RenderPassList& render_passes_in_draw_order) { | 179 void DirectRenderer::DrawFrame(RenderPassList& render_passes_in_draw_order) { |
180 TRACE_EVENT0("cc", "DirectRenderer::drawFrame"); | 180 TRACE_EVENT0("cc", "DirectRenderer::DrawFrame"); |
181 UMA_HISTOGRAM_COUNTS("Renderer4.renderPassCount", | 181 UMA_HISTOGRAM_COUNTS("Renderer4.renderPassCount", |
182 render_passes_in_draw_order.size()); | 182 render_passes_in_draw_order.size()); |
183 | 183 |
184 const RenderPass* root_render_pass = render_passes_in_draw_order.back(); | 184 const RenderPass* root_render_pass = render_passes_in_draw_order.back(); |
185 DCHECK(root_render_pass); | 185 DCHECK(root_render_pass); |
186 | 186 |
187 DrawingFrame frame; | 187 DrawingFrame frame; |
188 frame.root_render_pass = root_render_pass; | 188 frame.root_render_pass = root_render_pass; |
189 frame.root_damage_rect = | 189 frame.root_damage_rect = |
190 Capabilities().using_partial_swap ? | 190 Capabilities().using_partial_swap ? |
191 root_render_pass->damage_rect : root_render_pass->output_rect; | 191 root_render_pass->damage_rect : root_render_pass->output_rect; |
192 frame.root_damage_rect.Intersect(gfx::Rect(gfx::Point(), ViewportSize())); | 192 frame.root_damage_rect.Intersect(gfx::Rect(gfx::Point(), ViewportSize())); |
193 | 193 |
194 BeginDrawingFrame(frame); | 194 BeginDrawingFrame(frame); |
195 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) | 195 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) |
196 DrawRenderPass(frame, render_passes_in_draw_order[i]); | 196 DrawRenderPass(frame, render_passes_in_draw_order[i]); |
197 FinishDrawingFrame(frame); | 197 FinishDrawingFrame(frame); |
198 | 198 |
199 render_passes_in_draw_order.clear(); | 199 render_passes_in_draw_order.clear(); |
200 } | 200 } |
201 | 201 |
202 gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass( | 202 gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass( |
203 const DrawingFrame& frame) { | 203 const DrawingFrame& frame) { |
204 gfx::RectF render_pass_scissor = frame.current_render_pass->output_rect; | 204 gfx::RectF render_pass_scissor = frame.current_render_pass->output_rect; |
205 | 205 |
206 if (frame.root_damage_rect == frame.root_render_pass->output_rect) | 206 if (frame.root_damage_rect == frame.root_render_pass->output_rect) |
207 return render_pass_scissor; | 207 return render_pass_scissor; |
208 | 208 |
209 gfx::Transform inverseTransform(gfx::Transform::kSkipInitialization); | 209 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
210 if (frame.current_render_pass->transform_to_root_target.GetInverse( | 210 if (frame.current_render_pass->transform_to_root_target.GetInverse( |
211 &inverseTransform)) { | 211 &inverse_transform)) { |
212 // Only intersect inverse-projected damage if the transform is invertible. | 212 // Only intersect inverse-projected damage if the transform is invertible. |
213 gfx::RectF damage_rect_in_render_pass_space = | 213 gfx::RectF damage_rect_in_render_pass_space = |
214 MathUtil::ProjectClippedRect(inverseTransform, frame.root_damage_rect); | 214 MathUtil::ProjectClippedRect(inverse_transform, frame.root_damage_rect); |
215 render_pass_scissor.Intersect(damage_rect_in_render_pass_space); | 215 render_pass_scissor.Intersect(damage_rect_in_render_pass_space); |
216 } | 216 } |
217 | 217 |
218 return render_pass_scissor; | 218 return render_pass_scissor; |
219 } | 219 } |
220 | 220 |
221 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame& frame, | 221 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame& frame, |
222 const DrawQuad& quad) { | 222 const DrawQuad& quad) { |
223 if (quad.isClipped()) { | 223 if (quad.isClipped()) { |
224 gfx::RectF quad_scissor_rect = quad.clipRect(); | 224 gfx::RectF quad_scissor_rect = quad.clipRect(); |
(...skipping 19 matching lines...) Expand all Loading... |
244 } | 244 } |
245 | 245 |
246 *should_skip_quad = false; | 246 *should_skip_quad = false; |
247 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect)); | 247 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect)); |
248 } | 248 } |
249 | 249 |
250 void DirectRenderer::FinishDrawingQuadList() {} | 250 void DirectRenderer::FinishDrawingQuadList() {} |
251 | 251 |
252 void DirectRenderer::DrawRenderPass(DrawingFrame& frame, | 252 void DirectRenderer::DrawRenderPass(DrawingFrame& frame, |
253 const RenderPass* render_pass) { | 253 const RenderPass* render_pass) { |
254 TRACE_EVENT0("cc", "DirectRenderer::drawRenderPass"); | 254 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); |
255 if (!UseRenderPass(frame, render_pass)) | 255 if (!UseRenderPass(frame, render_pass)) |
256 return; | 256 return; |
257 | 257 |
258 bool using_scissor_as_optimization = Capabilities().using_partial_swap; | 258 bool using_scissor_as_optimization = Capabilities().using_partial_swap; |
259 gfx::RectF render_pass_scissor; | 259 gfx::RectF render_pass_scissor; |
260 | 260 |
261 if (using_scissor_as_optimization) { | 261 if (using_scissor_as_optimization) { |
262 render_pass_scissor = ComputeScissorRectForRenderPass(frame); | 262 render_pass_scissor = ComputeScissorRectForRenderPass(frame); |
263 SetScissorTestRect(MoveScissorToWindowSpace(frame, render_pass_scissor)); | 263 SetScissorTestRect(MoveScissorToWindowSpace(frame, render_pass_scissor)); |
264 } | 264 } |
265 | 265 |
266 if (frame.current_render_pass != frame.root_render_pass || | 266 if (frame.current_render_pass != frame.root_render_pass || |
267 client_->ShouldClearRootRenderPass()) { | 267 client_->ShouldClearRootRenderPass()) { |
268 if (!using_scissor_as_optimization) | 268 if (!using_scissor_as_optimization) |
269 EnsureScissorTestDisabled(); | 269 EnsureScissorTestDisabled(); |
270 ClearFramebuffer(frame); | 270 ClearFramebuffer(frame); |
271 } | 271 } |
272 | 272 |
273 const QuadList& quad_list = render_pass->quad_list; | 273 const QuadList& quad_list = render_pass->quad_list; |
274 for (QuadList::constBackToFrontIterator it = quad_list.backToFrontBegin(); | 274 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin(); |
275 it != quad_list.backToFrontEnd(); | 275 it != quad_list.BackToFrontEnd(); |
276 ++it) { | 276 ++it) { |
277 const DrawQuad& quad = *(*it); | 277 const DrawQuad& quad = *(*it); |
278 bool should_skip_quad = false; | 278 bool should_skip_quad = false; |
279 | 279 |
280 if (using_scissor_as_optimization) { | 280 if (using_scissor_as_optimization) { |
281 SetScissorStateForQuadWithRenderPassScissor( | 281 SetScissorStateForQuadWithRenderPassScissor( |
282 frame, quad, render_pass_scissor, &should_skip_quad); | 282 frame, quad, render_pass_scissor, &should_skip_quad); |
283 } else { | 283 } else { |
284 SetScissorStateForQuad(frame, quad); | 284 SetScissorStateForQuad(frame, quad); |
285 } | 285 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 336 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
337 return render_pass->output_rect.size(); | 337 return render_pass->output_rect.size(); |
338 } | 338 } |
339 | 339 |
340 // static | 340 // static |
341 GLenum DirectRenderer::RenderPassTextureFormat(const RenderPass* render_pass) { | 341 GLenum DirectRenderer::RenderPassTextureFormat(const RenderPass* render_pass) { |
342 return GL_RGBA; | 342 return GL_RGBA; |
343 } | 343 } |
344 | 344 |
345 } // namespace cc | 345 } // namespace cc |
OLD | NEW |