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 <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 // static | 72 // static |
73 void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform, | 73 void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform, |
74 const gfx::Transform& quad_transform, | 74 const gfx::Transform& quad_transform, |
75 const gfx::RectF& quad_rect) { | 75 const gfx::RectF& quad_rect) { |
76 *quad_rect_transform = quad_transform; | 76 *quad_rect_transform = quad_transform; |
77 quad_rect_transform->Translate(0.5 * quad_rect.width() + quad_rect.x(), | 77 quad_rect_transform->Translate(0.5 * quad_rect.width() + quad_rect.x(), |
78 0.5 * quad_rect.height() + quad_rect.y()); | 78 0.5 * quad_rect.height() + quad_rect.y()); |
79 quad_rect_transform->Scale(quad_rect.width(), quad_rect.height()); | 79 quad_rect_transform->Scale(quad_rect.width(), quad_rect.height()); |
80 } | 80 } |
81 | 81 |
82 // static | 82 void DirectRenderer::InitializeViewport(DrawingFrame* frame, |
83 void DirectRenderer::InitializeMatrices(DrawingFrame* frame, | |
84 gfx::Rect draw_rect, | 83 gfx::Rect draw_rect, |
84 gfx::Rect viewport_rect, | |
85 gfx::Size surface_size, | |
85 bool flip_y) { | 86 bool flip_y) { |
87 DCHECK_LE(viewport_rect.right(), surface_size.width()); | |
88 DCHECK_LE(viewport_rect.bottom(), surface_size.height()); | |
enne (OOO)
2013/06/06 19:07:49
DCHECK_GT(viewport_rect.x(), 0)
DCHECK_GT(viewport
| |
86 if (flip_y) { | 89 if (flip_y) { |
87 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), | 90 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), |
88 draw_rect.right(), | 91 draw_rect.right(), |
89 draw_rect.bottom(), | 92 draw_rect.bottom(), |
90 draw_rect.y()); | 93 draw_rect.y()); |
91 } else { | 94 } else { |
92 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), | 95 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), |
93 draw_rect.right(), | 96 draw_rect.right(), |
94 draw_rect.y(), | 97 draw_rect.y(), |
95 draw_rect.bottom()); | 98 draw_rect.bottom()); |
96 } | 99 } |
97 frame->window_matrix = | 100 |
98 window_matrix(0, 0, draw_rect.width(), draw_rect.height()); | 101 gfx::Rect window_rect = viewport_rect; |
102 if (flip_y) | |
103 window_rect.set_y(surface_size.height() - viewport_rect.bottom()); | |
104 frame->window_matrix = window_matrix(window_rect.x(), | |
105 window_rect.y(), | |
106 window_rect.width(), | |
107 window_rect.height()); | |
108 SetDrawViewport(window_rect); | |
109 | |
99 frame->flipped_y = flip_y; | 110 frame->flipped_y = flip_y; |
111 | |
112 current_draw_rect_ = draw_rect; | |
113 current_viewport_rect_ = viewport_rect; | |
114 current_surface_size_ = surface_size; | |
100 } | 115 } |
101 | 116 |
102 // static | 117 gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace( |
103 gfx::Rect DirectRenderer::MoveScissorToWindowSpace( | 118 const gfx::RectF& draw_rect, bool flip_y) const { |
104 const DrawingFrame* frame, const gfx::RectF& scissor_rect) { | 119 gfx::Rect window_rect = gfx::ToEnclosingRect(draw_rect); |
105 gfx::Rect scissor_rect_in_canvas_space = gfx::ToEnclosingRect(scissor_rect); | 120 window_rect -= current_draw_rect_.OffsetFromOrigin(); |
106 // The scissor coordinates must be supplied in viewport space so we need to | 121 window_rect += current_viewport_rect_.OffsetFromOrigin(); |
107 // offset by the relative position of the top left corner of the current | 122 if (flip_y) |
108 // render pass. | 123 window_rect.set_y(current_surface_size_.height() - window_rect.bottom()); |
109 gfx::Rect framebuffer_output_rect = frame->current_render_pass->output_rect; | 124 return window_rect; |
110 scissor_rect_in_canvas_space.set_x( | |
111 scissor_rect_in_canvas_space.x() - framebuffer_output_rect.x()); | |
112 if (frame->flipped_y && !frame->current_texture) { | |
113 scissor_rect_in_canvas_space.set_y( | |
114 framebuffer_output_rect.height() - | |
115 (scissor_rect_in_canvas_space.bottom() - framebuffer_output_rect.y())); | |
116 } else { | |
117 scissor_rect_in_canvas_space.set_y( | |
118 scissor_rect_in_canvas_space.y() - framebuffer_output_rect.y()); | |
119 } | |
120 return scissor_rect_in_canvas_space; | |
121 } | 125 } |
122 | 126 |
123 DirectRenderer::DirectRenderer(RendererClient* client, | 127 DirectRenderer::DirectRenderer(RendererClient* client, |
128 OutputSurface* output_surface, | |
124 ResourceProvider* resource_provider) | 129 ResourceProvider* resource_provider) |
125 : Renderer(client), | 130 : Renderer(client), |
131 output_surface_(output_surface), | |
126 resource_provider_(resource_provider) {} | 132 resource_provider_(resource_provider) {} |
127 | 133 |
128 DirectRenderer::~DirectRenderer() {} | 134 DirectRenderer::~DirectRenderer() {} |
129 | 135 |
130 bool DirectRenderer::CanReadPixels() const { return true; } | 136 bool DirectRenderer::CanReadPixels() const { return true; } |
131 | 137 |
132 void DirectRenderer::SetEnlargePassTextureAmountForTesting( | 138 void DirectRenderer::SetEnlargePassTextureAmountForTesting( |
133 gfx::Vector2d amount) { | 139 gfx::Vector2d amount) { |
134 enlarge_pass_texture_amount_ = amount; | 140 enlarge_pass_texture_amount_ = amount; |
135 } | 141 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 render_passes_in_draw_order->size()); | 196 render_passes_in_draw_order->size()); |
191 | 197 |
192 const RenderPass* root_render_pass = render_passes_in_draw_order->back(); | 198 const RenderPass* root_render_pass = render_passes_in_draw_order->back(); |
193 DCHECK(root_render_pass); | 199 DCHECK(root_render_pass); |
194 | 200 |
195 DrawingFrame frame; | 201 DrawingFrame frame; |
196 frame.root_render_pass = root_render_pass; | 202 frame.root_render_pass = root_render_pass; |
197 frame.root_damage_rect = | 203 frame.root_damage_rect = |
198 Capabilities().using_partial_swap && client_->AllowPartialSwap() ? | 204 Capabilities().using_partial_swap && client_->AllowPartialSwap() ? |
199 root_render_pass->damage_rect : root_render_pass->output_rect; | 205 root_render_pass->damage_rect : root_render_pass->output_rect; |
200 frame.root_damage_rect.Intersect(gfx::Rect(ViewportSize())); | 206 frame.root_damage_rect.Intersect(gfx::Rect(client_->DeviceViewport().size())); |
207 | |
208 // Only reshape when we know we are going to draw. Otherwise, the reshape | |
209 // can leave the window at the wrong size if we never draw and the proper | |
210 // viewport size is never set. | |
211 output_surface_->Reshape(client_->DeviceViewport().size(), | |
212 client_->DeviceScaleFactor()); | |
201 | 213 |
202 BeginDrawingFrame(&frame); | 214 BeginDrawingFrame(&frame); |
203 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { | 215 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { |
204 RenderPass* pass = render_passes_in_draw_order->at(i); | 216 RenderPass* pass = render_passes_in_draw_order->at(i); |
205 DrawRenderPass(&frame, pass); | 217 DrawRenderPass(&frame, pass); |
206 | 218 |
207 for (ScopedPtrVector<CopyOutputRequest>::iterator it = | 219 for (ScopedPtrVector<CopyOutputRequest>::iterator it = |
208 pass->copy_requests.begin(); | 220 pass->copy_requests.begin(); |
209 it != pass->copy_requests.end(); | 221 it != pass->copy_requests.end(); |
210 ++it) { | 222 ++it) { |
(...skipping 27 matching lines...) Expand all Loading... | |
238 render_pass_scissor.Intersect(damage_rect_in_render_pass_space); | 250 render_pass_scissor.Intersect(damage_rect_in_render_pass_space); |
239 } | 251 } |
240 | 252 |
241 return render_pass_scissor; | 253 return render_pass_scissor; |
242 } | 254 } |
243 | 255 |
244 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame, | 256 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame, |
245 const DrawQuad& quad) { | 257 const DrawQuad& quad) { |
246 if (quad.isClipped()) { | 258 if (quad.isClipped()) { |
247 gfx::RectF quad_scissor_rect = quad.clipRect(); | 259 gfx::RectF quad_scissor_rect = quad.clipRect(); |
248 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect)); | 260 SetScissorTestRect( |
261 MoveFromDrawToWindowSpace(quad_scissor_rect, frame->flipped_y)); | |
249 } else { | 262 } else { |
250 EnsureScissorTestDisabled(); | 263 EnsureScissorTestDisabled(); |
251 } | 264 } |
252 } | 265 } |
253 | 266 |
254 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( | 267 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( |
255 const DrawingFrame* frame, | 268 const DrawingFrame* frame, |
256 const DrawQuad& quad, | 269 const DrawQuad& quad, |
257 const gfx::RectF& render_pass_scissor, | 270 const gfx::RectF& render_pass_scissor, |
258 bool* should_skip_quad) { | 271 bool* should_skip_quad) { |
259 gfx::RectF quad_scissor_rect = render_pass_scissor; | 272 gfx::RectF quad_scissor_rect = render_pass_scissor; |
260 | 273 |
261 if (quad.isClipped()) | 274 if (quad.isClipped()) |
262 quad_scissor_rect.Intersect(quad.clipRect()); | 275 quad_scissor_rect.Intersect(quad.clipRect()); |
263 | 276 |
264 if (quad_scissor_rect.IsEmpty()) { | 277 if (quad_scissor_rect.IsEmpty()) { |
265 *should_skip_quad = true; | 278 *should_skip_quad = true; |
266 return; | 279 return; |
267 } | 280 } |
268 | 281 |
269 *should_skip_quad = false; | 282 *should_skip_quad = false; |
270 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect)); | 283 SetScissorTestRect( |
284 MoveFromDrawToWindowSpace(quad_scissor_rect, frame->flipped_y)); | |
271 } | 285 } |
272 | 286 |
273 void DirectRenderer::FinishDrawingQuadList() {} | 287 void DirectRenderer::FinishDrawingQuadList() {} |
274 | 288 |
275 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, | 289 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, |
276 const RenderPass* render_pass) { | 290 const RenderPass* render_pass) { |
277 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); | 291 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); |
278 if (!UseRenderPass(frame, render_pass)) | 292 if (!UseRenderPass(frame, render_pass)) |
279 return; | 293 return; |
280 | 294 |
281 bool using_scissor_as_optimization = | 295 bool using_scissor_as_optimization = |
282 Capabilities().using_partial_swap && client_->AllowPartialSwap(); | 296 Capabilities().using_partial_swap && client_->AllowPartialSwap(); |
283 gfx::RectF render_pass_scissor; | 297 gfx::RectF render_pass_scissor; |
284 | 298 |
285 if (using_scissor_as_optimization) { | 299 if (using_scissor_as_optimization) { |
286 render_pass_scissor = ComputeScissorRectForRenderPass(frame); | 300 render_pass_scissor = ComputeScissorRectForRenderPass(frame); |
287 SetScissorTestRect(MoveScissorToWindowSpace(frame, render_pass_scissor)); | 301 SetScissorTestRect( |
302 MoveFromDrawToWindowSpace(render_pass_scissor, frame->flipped_y)); | |
288 } | 303 } |
289 | 304 |
290 if (frame->current_render_pass != frame->root_render_pass || | 305 if (frame->current_render_pass != frame->root_render_pass || |
291 client_->ShouldClearRootRenderPass()) { | 306 client_->ShouldClearRootRenderPass()) { |
292 if (!using_scissor_as_optimization) | 307 if (!using_scissor_as_optimization) |
293 EnsureScissorTestDisabled(); | 308 EnsureScissorTestDisabled(); |
294 ClearFramebuffer(frame); | 309 ClearFramebuffer(frame); |
295 } | 310 } |
296 | 311 |
297 const QuadList& quad_list = render_pass->quad_list; | 312 const QuadList& quad_list = render_pass->quad_list; |
(...skipping 22 matching lines...) Expand all Loading... | |
320 } | 335 } |
321 } | 336 } |
322 | 337 |
323 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, | 338 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, |
324 const RenderPass* render_pass) { | 339 const RenderPass* render_pass) { |
325 frame->current_render_pass = render_pass; | 340 frame->current_render_pass = render_pass; |
326 frame->current_texture = NULL; | 341 frame->current_texture = NULL; |
327 | 342 |
328 if (render_pass == frame->root_render_pass) { | 343 if (render_pass == frame->root_render_pass) { |
329 BindFramebufferToOutputSurface(frame); | 344 BindFramebufferToOutputSurface(frame); |
330 InitializeMatrices(frame, render_pass->output_rect, FlippedFramebuffer()); | 345 InitializeViewport(frame, |
331 SetDrawViewportSize(render_pass->output_rect.size()); | 346 render_pass->output_rect, |
347 client_->DeviceViewport(), | |
348 output_surface_->SurfaceSize(), | |
349 FlippedFramebuffer()); | |
332 return true; | 350 return true; |
333 } | 351 } |
334 | 352 |
335 if (!resource_provider_) | 353 if (!resource_provider_) |
336 return false; | 354 return false; |
337 | 355 |
338 CachedResource* texture = render_pass_textures_.get(render_pass->id); | 356 CachedResource* texture = render_pass_textures_.get(render_pass->id); |
339 DCHECK(texture); | 357 DCHECK(texture); |
340 | 358 |
341 gfx::Size size = RenderPassTextureSize(render_pass); | 359 gfx::Size size = RenderPassTextureSize(render_pass); |
(...skipping 21 matching lines...) Expand all Loading... | |
363 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 381 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
364 return render_pass->output_rect.size(); | 382 return render_pass->output_rect.size(); |
365 } | 383 } |
366 | 384 |
367 // static | 385 // static |
368 GLenum DirectRenderer::RenderPassTextureFormat(const RenderPass* render_pass) { | 386 GLenum DirectRenderer::RenderPassTextureFormat(const RenderPass* render_pass) { |
369 return GL_RGBA; | 387 return GL_RGBA; |
370 } | 388 } |
371 | 389 |
372 } // namespace cc | 390 } // namespace cc |
OLD | NEW |