Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: cc/output/direct_renderer.cc

Issue 2680203005: cc: Use DrawingFrame as state, not function argument (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/output/direct_renderer.h ('k') | cc/output/gl_renderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <unordered_map> 9 #include <unordered_map>
10 #include <utility> 10 #include <utility>
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 107 }
108 108
109 void DirectRenderer::InitializeViewport(DrawingFrame* frame, 109 void DirectRenderer::InitializeViewport(DrawingFrame* frame,
110 const gfx::Rect& draw_rect, 110 const gfx::Rect& draw_rect,
111 const gfx::Rect& viewport_rect, 111 const gfx::Rect& viewport_rect,
112 const gfx::Size& surface_size) { 112 const gfx::Size& surface_size) {
113 DCHECK_GE(viewport_rect.x(), 0); 113 DCHECK_GE(viewport_rect.x(), 0);
114 DCHECK_GE(viewport_rect.y(), 0); 114 DCHECK_GE(viewport_rect.y(), 0);
115 DCHECK_LE(viewport_rect.right(), surface_size.width()); 115 DCHECK_LE(viewport_rect.right(), surface_size.width());
116 DCHECK_LE(viewport_rect.bottom(), surface_size.height()); 116 DCHECK_LE(viewport_rect.bottom(), surface_size.height());
117 bool flip_y = FlippedFramebuffer(frame); 117 bool flip_y = FlippedFramebuffer();
118 if (flip_y) { 118 if (flip_y) {
119 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), 119 frame->projection_matrix = OrthoProjectionMatrix(
120 draw_rect.right(), 120 draw_rect.x(), draw_rect.right(), draw_rect.bottom(), draw_rect.y());
121 draw_rect.bottom(),
122 draw_rect.y());
123 } else { 121 } else {
124 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), 122 frame->projection_matrix = OrthoProjectionMatrix(
125 draw_rect.right(), 123 draw_rect.x(), draw_rect.right(), draw_rect.y(), draw_rect.bottom());
126 draw_rect.y(),
127 draw_rect.bottom());
128 } 124 }
129 125
130 gfx::Rect window_rect = viewport_rect; 126 gfx::Rect window_rect = viewport_rect;
131 if (flip_y) 127 if (flip_y)
132 window_rect.set_y(surface_size.height() - viewport_rect.bottom()); 128 window_rect.set_y(surface_size.height() - viewport_rect.bottom());
133 frame->window_matrix = window_matrix(window_rect.x(), 129 frame->window_matrix =
134 window_rect.y(), 130 window_matrix(window_rect.x(), window_rect.y(), window_rect.width(),
135 window_rect.width(), 131 window_rect.height());
136 window_rect.height());
137 current_draw_rect_ = draw_rect; 132 current_draw_rect_ = draw_rect;
138 current_viewport_rect_ = viewport_rect; 133 current_viewport_rect_ = viewport_rect;
139 current_surface_size_ = surface_size; 134 current_surface_size_ = surface_size;
140 current_window_space_viewport_ = window_rect; 135 current_window_space_viewport_ = window_rect;
141 } 136 }
142 137
143 gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace( 138 gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace(
144 const DrawingFrame* frame,
145 const gfx::Rect& draw_rect) const { 139 const gfx::Rect& draw_rect) const {
146 gfx::Rect window_rect = draw_rect; 140 gfx::Rect window_rect = draw_rect;
147 window_rect -= current_draw_rect_.OffsetFromOrigin(); 141 window_rect -= current_draw_rect_.OffsetFromOrigin();
148 window_rect += current_viewport_rect_.OffsetFromOrigin(); 142 window_rect += current_viewport_rect_.OffsetFromOrigin();
149 if (FlippedFramebuffer(frame)) 143 if (FlippedFramebuffer())
150 window_rect.set_y(current_surface_size_.height() - window_rect.bottom()); 144 window_rect.set_y(current_surface_size_.height() - window_rect.bottom());
151 return window_rect; 145 return window_rect;
152 } 146 }
153 147
154 const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly( 148 const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly(
155 const RenderPass* pass) { 149 const RenderPass* pass) {
156 return nullptr; 150 return nullptr;
157 } 151 }
158 152
159 void DirectRenderer::SetVisible(bool visible) { 153 void DirectRenderer::SetVisible(bool visible) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 DLOG_IF(WARNING, !overdraw_feedback_support_missing_logged_once_) 231 DLOG_IF(WARNING, !overdraw_feedback_support_missing_logged_once_)
238 << "Overdraw feedback enabled on platform without support."; 232 << "Overdraw feedback enabled on platform without support.";
239 overdraw_feedback_support_missing_logged_once_ = true; 233 overdraw_feedback_support_missing_logged_once_ = true;
240 #endif 234 #endif
241 overdraw_feedback = false; 235 overdraw_feedback = false;
242 } 236 }
243 base::AutoReset<bool> auto_reset_overdraw_feedback(&overdraw_feedback_, 237 base::AutoReset<bool> auto_reset_overdraw_feedback(&overdraw_feedback_,
244 overdraw_feedback); 238 overdraw_feedback);
245 239
246 DrawingFrame frame; 240 DrawingFrame frame;
247 frame.render_passes_in_draw_order = render_passes_in_draw_order; 241 current_frame_ = &frame;
enne (OOO) 2017/02/08 22:32:40 In general I'm pretty fine with keeping the frame
ccameron 2017/02/08 22:35:59 That was what I originally had in the patch, but t
248 frame.root_render_pass = root_render_pass; 242 current_frame_->render_passes_in_draw_order = render_passes_in_draw_order;
249 frame.root_damage_rect = root_render_pass->damage_rect; 243 current_frame_->root_render_pass = root_render_pass;
250 frame.root_damage_rect.Union(overlay_processor_->GetAndResetOverlayDamage()); 244 current_frame_->root_damage_rect = root_render_pass->damage_rect;
251 frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_size)); 245 current_frame_->root_damage_rect.Union(
252 frame.device_viewport_size = device_viewport_size; 246 overlay_processor_->GetAndResetOverlayDamage());
253 frame.device_color_space = device_color_space; 247 current_frame_->root_damage_rect.Intersect(gfx::Rect(device_viewport_size));
248 current_frame_->device_viewport_size = device_viewport_size;
249 current_frame_->device_color_space = device_color_space;
254 250
255 // Only reshape when we know we are going to draw. Otherwise, the reshape 251 // Only reshape when we know we are going to draw. Otherwise, the reshape
256 // can leave the window at the wrong size if we never draw and the proper 252 // can leave the window at the wrong size if we never draw and the proper
257 // viewport size is never set. 253 // viewport size is never set.
258 bool frame_has_alpha = frame.root_render_pass->has_transparent_background; 254 bool frame_has_alpha =
255 current_frame_->root_render_pass->has_transparent_background;
259 bool use_stencil = overdraw_feedback_; 256 bool use_stencil = overdraw_feedback_;
260 if (device_viewport_size != reshape_surface_size_ || 257 if (device_viewport_size != reshape_surface_size_ ||
261 device_scale_factor != reshape_device_scale_factor_ || 258 device_scale_factor != reshape_device_scale_factor_ ||
262 device_color_space != reshape_device_color_space_ || 259 device_color_space != reshape_device_color_space_ ||
263 frame_has_alpha != reshape_has_alpha_ || 260 frame_has_alpha != reshape_has_alpha_ ||
264 use_stencil != reshape_use_stencil_) { 261 use_stencil != reshape_use_stencil_) {
265 reshape_surface_size_ = device_viewport_size; 262 reshape_surface_size_ = device_viewport_size;
266 reshape_device_scale_factor_ = device_scale_factor; 263 reshape_device_scale_factor_ = device_scale_factor;
267 reshape_device_color_space_ = device_color_space; 264 reshape_device_color_space_ = device_color_space;
268 reshape_has_alpha_ = frame.root_render_pass->has_transparent_background; 265 reshape_has_alpha_ =
266 current_frame_->root_render_pass->has_transparent_background;
269 reshape_use_stencil_ = overdraw_feedback_; 267 reshape_use_stencil_ = overdraw_feedback_;
270 output_surface_->Reshape( 268 output_surface_->Reshape(
271 reshape_surface_size_, reshape_device_scale_factor_, 269 reshape_surface_size_, reshape_device_scale_factor_,
272 reshape_device_color_space_, reshape_has_alpha_, reshape_use_stencil_); 270 reshape_device_color_space_, reshape_has_alpha_, reshape_use_stencil_);
273 } 271 }
274 272
275 BeginDrawingFrame(&frame); 273 BeginDrawingFrame();
276 274
277 for (const auto& pass : *render_passes_in_draw_order) { 275 for (const auto& pass : *render_passes_in_draw_order) {
278 if (!pass->filters.IsEmpty()) 276 if (!pass->filters.IsEmpty())
279 render_pass_filters_.push_back(std::make_pair(pass->id, &pass->filters)); 277 render_pass_filters_.push_back(std::make_pair(pass->id, &pass->filters));
280 if (!pass->background_filters.IsEmpty()) { 278 if (!pass->background_filters.IsEmpty()) {
281 render_pass_background_filters_.push_back( 279 render_pass_background_filters_.push_back(
282 std::make_pair(pass->id, &pass->background_filters)); 280 std::make_pair(pass->id, &pass->background_filters));
283 } 281 }
284 std::sort(render_pass_filters_.begin(), render_pass_filters_.end()); 282 std::sort(render_pass_filters_.begin(), render_pass_filters_.end());
285 std::sort(render_pass_background_filters_.begin(), 283 std::sort(render_pass_background_filters_.begin(),
286 render_pass_background_filters_.end()); 284 render_pass_background_filters_.end());
287 } 285 }
288 286
289 // Draw all non-root render passes except for the root render pass. 287 // Draw all non-root render passes except for the root render pass.
290 for (const auto& pass : *render_passes_in_draw_order) { 288 for (const auto& pass : *render_passes_in_draw_order) {
291 if (pass.get() == root_render_pass) 289 if (pass.get() == root_render_pass)
292 break; 290 break;
293 DrawRenderPassAndExecuteCopyRequests(&frame, pass.get()); 291 DrawRenderPassAndExecuteCopyRequests(pass.get());
294 } 292 }
295 293
296 // Create the overlay candidate for the output surface, and mark it as 294 // Create the overlay candidate for the output surface, and mark it as
297 // always handled. 295 // always handled.
298 if (output_surface_->IsDisplayedAsOverlayPlane()) { 296 if (output_surface_->IsDisplayedAsOverlayPlane()) {
299 OverlayCandidate output_surface_plane; 297 OverlayCandidate output_surface_plane;
300 output_surface_plane.display_rect = 298 output_surface_plane.display_rect =
301 gfx::RectF(root_render_pass->output_rect); 299 gfx::RectF(root_render_pass->output_rect);
302 output_surface_plane.quad_rect_in_target_space = 300 output_surface_plane.quad_rect_in_target_space =
303 root_render_pass->output_rect; 301 root_render_pass->output_rect;
304 output_surface_plane.use_output_surface_for_resource = true; 302 output_surface_plane.use_output_surface_for_resource = true;
305 output_surface_plane.overlay_handled = true; 303 output_surface_plane.overlay_handled = true;
306 frame.overlay_list.push_back(output_surface_plane); 304 current_frame_->overlay_list.push_back(output_surface_plane);
307 } 305 }
308 306
309 // Attempt to replace some or all of the quads of the root render pass with 307 // Attempt to replace some or all of the quads of the root render pass with
310 // overlays. 308 // overlays.
311 overlay_processor_->ProcessForOverlays( 309 overlay_processor_->ProcessForOverlays(
312 resource_provider_, root_render_pass, render_pass_filters_, 310 resource_provider_, root_render_pass, render_pass_filters_,
313 render_pass_background_filters_, &frame.overlay_list, 311 render_pass_background_filters_, &current_frame_->overlay_list,
314 &frame.ca_layer_overlay_list, &frame.root_damage_rect); 312 &current_frame_->ca_layer_overlay_list,
313 &current_frame_->root_damage_rect);
315 314
316 // We can skip all drawing if the damage rect is now empty. 315 // We can skip all drawing if the damage rect is now empty.
317 bool skip_drawing_root_render_pass = 316 bool skip_drawing_root_render_pass =
318 frame.root_damage_rect.IsEmpty() && allow_empty_swap_; 317 current_frame_->root_damage_rect.IsEmpty() && allow_empty_swap_;
319 318
320 // If we have to draw but don't support partial swap, the whole output should 319 // If we have to draw but don't support partial swap, the whole output should
321 // be considered damaged. 320 // be considered damaged.
322 if (!skip_drawing_root_render_pass && !use_partial_swap_) 321 if (!skip_drawing_root_render_pass && !use_partial_swap_)
323 frame.root_damage_rect = root_render_pass->output_rect; 322 current_frame_->root_damage_rect = root_render_pass->output_rect;
324 323
325 if (skip_drawing_root_render_pass) { 324 if (skip_drawing_root_render_pass) {
326 // If any of the overlays is the output surface, then ensure that the 325 // If any of the overlays is the output surface, then ensure that the
327 // backbuffer be allocated (allocation of the backbuffer is a side-effect 326 // backbuffer be allocated (allocation of the backbuffer is a side-effect
328 // of BindFramebufferToOutputSurface). 327 // of BindFramebufferToOutputSurface).
329 for (auto& overlay : frame.overlay_list) { 328 for (auto& overlay : current_frame_->overlay_list) {
330 if (overlay.use_output_surface_for_resource) { 329 if (overlay.use_output_surface_for_resource) {
331 BindFramebufferToOutputSurface(&frame); 330 BindFramebufferToOutputSurface();
332 break; 331 break;
333 } 332 }
334 } 333 }
335 } else { 334 } else {
336 DrawRenderPassAndExecuteCopyRequests(&frame, root_render_pass); 335 DrawRenderPassAndExecuteCopyRequests(root_render_pass);
337 } 336 }
338 337
339 FinishDrawingFrame(&frame); 338 FinishDrawingFrame();
340 render_passes_in_draw_order->clear(); 339 render_passes_in_draw_order->clear();
341 render_pass_filters_.clear(); 340 render_pass_filters_.clear();
342 render_pass_background_filters_.clear(); 341 render_pass_background_filters_.clear();
342 current_frame_ = nullptr;
343 } 343 }
344 344
345 gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( 345 gfx::Rect DirectRenderer::DrawingFrame::ComputeScissorRectForRenderPass()
346 const DrawingFrame* frame) { 346 const {
347 if (frame->current_render_pass == frame->root_render_pass) 347 if (current_render_pass == root_render_pass)
348 return frame->root_damage_rect; 348 return root_damage_rect;
349 349
350 // If the root damage rect has been expanded due to overlays, all the other 350 // If the root damage rect has been expanded due to overlays, all the other
351 // damage rect calculations are incorrect. 351 // damage rect calculations are incorrect.
352 if (!frame->root_render_pass->damage_rect.Contains(frame->root_damage_rect)) 352 if (!root_render_pass->damage_rect.Contains(root_damage_rect))
353 return frame->current_render_pass->output_rect; 353 return current_render_pass->output_rect;
354 354
355 DCHECK(frame->current_render_pass->copy_requests.empty() || 355 DCHECK(
356 (frame->current_render_pass->damage_rect == 356 current_render_pass->copy_requests.empty() ||
357 frame->current_render_pass->output_rect)); 357 (current_render_pass->damage_rect == current_render_pass->output_rect));
358 return frame->current_render_pass->damage_rect; 358 return current_render_pass->damage_rect;
359 } 359 }
360 360
361 gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace( 361 gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace() const {
362 const DrawingFrame* frame) const { 362 gfx::Rect device_viewport_rect(current_frame_->device_viewport_size);
363 gfx::Rect device_viewport_rect(frame->device_viewport_size);
364 device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin(); 363 device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin();
365 device_viewport_rect += current_draw_rect_.OffsetFromOrigin(); 364 device_viewport_rect += current_draw_rect_.OffsetFromOrigin();
366 return device_viewport_rect; 365 return device_viewport_rect;
367 } 366 }
368 367
369 gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace( 368 gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace() const {
370 const DrawingFrame* frame) const { 369 if (current_frame_->current_render_pass == current_frame_->root_render_pass) {
371 if (frame->current_render_pass == frame->root_render_pass) { 370 gfx::Rect output_surface_rect(current_frame_->device_viewport_size);
372 gfx::Rect output_surface_rect(frame->device_viewport_size);
373 output_surface_rect -= current_viewport_rect_.OffsetFromOrigin(); 371 output_surface_rect -= current_viewport_rect_.OffsetFromOrigin();
374 output_surface_rect += current_draw_rect_.OffsetFromOrigin(); 372 output_surface_rect += current_draw_rect_.OffsetFromOrigin();
375 return output_surface_rect; 373 return output_surface_rect;
376 } else { 374 } else {
377 return frame->current_render_pass->output_rect; 375 return current_frame_->current_render_pass->output_rect;
378 } 376 }
379 } 377 }
380 378
381 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, 379 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad,
382 const gfx::Rect& render_pass_scissor) { 380 const gfx::Rect& render_pass_scissor) {
383 if (render_pass_scissor.IsEmpty()) 381 if (render_pass_scissor.IsEmpty())
384 return true; 382 return true;
385 383
386 if (quad.shared_quad_state->is_clipped) { 384 if (quad.shared_quad_state->is_clipped) {
387 gfx::Rect r = quad.shared_quad_state->clip_rect; 385 gfx::Rect r = quad.shared_quad_state->clip_rect;
388 r.Intersect(render_pass_scissor); 386 r.Intersect(render_pass_scissor);
389 return r.IsEmpty(); 387 return r.IsEmpty();
390 } 388 }
391 389
392 return false; 390 return false;
393 } 391 }
394 392
395 void DirectRenderer::SetScissorStateForQuad( 393 void DirectRenderer::SetScissorStateForQuad(
396 const DrawingFrame* frame,
397 const DrawQuad& quad, 394 const DrawQuad& quad,
398 const gfx::Rect& render_pass_scissor, 395 const gfx::Rect& render_pass_scissor,
399 bool use_render_pass_scissor) { 396 bool use_render_pass_scissor) {
400 if (use_render_pass_scissor) { 397 if (use_render_pass_scissor) {
401 gfx::Rect quad_scissor_rect = render_pass_scissor; 398 gfx::Rect quad_scissor_rect = render_pass_scissor;
402 if (quad.shared_quad_state->is_clipped) 399 if (quad.shared_quad_state->is_clipped)
403 quad_scissor_rect.Intersect(quad.shared_quad_state->clip_rect); 400 quad_scissor_rect.Intersect(quad.shared_quad_state->clip_rect);
404 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); 401 SetScissorTestRectInDrawSpace(quad_scissor_rect);
405 return; 402 return;
406 } else if (quad.shared_quad_state->is_clipped) { 403 } else if (quad.shared_quad_state->is_clipped) {
407 SetScissorTestRectInDrawSpace(frame, quad.shared_quad_state->clip_rect); 404 SetScissorTestRectInDrawSpace(quad.shared_quad_state->clip_rect);
408 return; 405 return;
409 } 406 }
410 407
411 EnsureScissorTestDisabled(); 408 EnsureScissorTestDisabled();
412 } 409 }
413 410
414 void DirectRenderer::SetScissorTestRectInDrawSpace( 411 void DirectRenderer::SetScissorTestRectInDrawSpace(
415 const DrawingFrame* frame,
416 const gfx::Rect& draw_space_rect) { 412 const gfx::Rect& draw_space_rect) {
417 gfx::Rect window_space_rect = 413 gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect);
418 MoveFromDrawToWindowSpace(frame, draw_space_rect);
419 SetScissorTestRect(window_space_rect); 414 SetScissorTestRect(window_space_rect);
420 } 415 }
421 416
422 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, 417 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly,
423 DrawingFrame* frame,
424 const gfx::Rect& render_pass_scissor, 418 const gfx::Rect& render_pass_scissor,
425 bool use_render_pass_scissor) { 419 bool use_render_pass_scissor) {
426 SetScissorStateForQuad(frame, *poly.original_ref(), render_pass_scissor, 420 SetScissorStateForQuad(*poly.original_ref(), render_pass_scissor,
427 use_render_pass_scissor); 421 use_render_pass_scissor);
428 422
429 // If the poly has not been split, then it is just a normal DrawQuad, 423 // If the poly has not been split, then it is just a normal DrawQuad,
430 // and we should save any extra processing that would have to be done. 424 // and we should save any extra processing that would have to be done.
431 if (!poly.is_split()) { 425 if (!poly.is_split()) {
432 DoDrawQuad(frame, poly.original_ref(), NULL); 426 DoDrawQuad(poly.original_ref(), NULL);
433 return; 427 return;
434 } 428 }
435 429
436 std::vector<gfx::QuadF> quads; 430 std::vector<gfx::QuadF> quads;
437 poly.ToQuads2D(&quads); 431 poly.ToQuads2D(&quads);
438 for (size_t i = 0; i < quads.size(); ++i) { 432 for (size_t i = 0; i < quads.size(); ++i) {
439 DoDrawQuad(frame, poly.original_ref(), &quads[i]); 433 DoDrawQuad(poly.original_ref(), &quads[i]);
440 } 434 }
441 } 435 }
442 436
443 const FilterOperations* DirectRenderer::FiltersForPass( 437 const FilterOperations* DirectRenderer::FiltersForPass(
444 int render_pass_id) const { 438 int render_pass_id) const {
445 auto it = std::lower_bound( 439 auto it = std::lower_bound(
446 render_pass_filters_.begin(), render_pass_filters_.end(), 440 render_pass_filters_.begin(), render_pass_filters_.end(),
447 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); 441 std::pair<int, FilterOperations*>(render_pass_id, nullptr));
448 if (it != render_pass_filters_.end() && it->first == render_pass_id) 442 if (it != render_pass_filters_.end() && it->first == render_pass_id)
449 return it->second; 443 return it->second;
450 return nullptr; 444 return nullptr;
451 } 445 }
452 446
453 const FilterOperations* DirectRenderer::BackgroundFiltersForPass( 447 const FilterOperations* DirectRenderer::BackgroundFiltersForPass(
454 int render_pass_id) const { 448 int render_pass_id) const {
455 auto it = std::lower_bound( 449 auto it = std::lower_bound(
456 render_pass_background_filters_.begin(), 450 render_pass_background_filters_.begin(),
457 render_pass_background_filters_.end(), 451 render_pass_background_filters_.end(),
458 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); 452 std::pair<int, FilterOperations*>(render_pass_id, nullptr));
459 if (it != render_pass_background_filters_.end() && 453 if (it != render_pass_background_filters_.end() &&
460 it->first == render_pass_id) 454 it->first == render_pass_id)
461 return it->second; 455 return it->second;
462 return nullptr; 456 return nullptr;
463 } 457 }
464 458
465 void DirectRenderer::FlushPolygons( 459 void DirectRenderer::FlushPolygons(
466 std::deque<std::unique_ptr<DrawPolygon>>* poly_list, 460 std::deque<std::unique_ptr<DrawPolygon>>* poly_list,
467 DrawingFrame* frame,
468 const gfx::Rect& render_pass_scissor, 461 const gfx::Rect& render_pass_scissor,
469 bool use_render_pass_scissor) { 462 bool use_render_pass_scissor) {
470 if (poly_list->empty()) { 463 if (poly_list->empty()) {
471 return; 464 return;
472 } 465 }
473 466
474 BspTree bsp_tree(poly_list); 467 BspTree bsp_tree(poly_list);
475 BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor, 468 BspWalkActionDrawPolygon action_handler(this, render_pass_scissor,
476 use_render_pass_scissor); 469 use_render_pass_scissor);
477 bsp_tree.TraverseWithActionHandler(&action_handler); 470 bsp_tree.TraverseWithActionHandler(&action_handler);
478 DCHECK(poly_list->empty()); 471 DCHECK(poly_list->empty());
479 } 472 }
480 473
481 void DirectRenderer::DrawRenderPassAndExecuteCopyRequests( 474 void DirectRenderer::DrawRenderPassAndExecuteCopyRequests(
482 DrawingFrame* frame,
483 RenderPass* render_pass) { 475 RenderPass* render_pass) {
484 if (render_pass_bypass_quads_.find(render_pass->id) != 476 if (render_pass_bypass_quads_.find(render_pass->id) !=
485 render_pass_bypass_quads_.end()) { 477 render_pass_bypass_quads_.end()) {
486 return; 478 return;
487 } 479 }
488 480
489 DrawRenderPass(frame, render_pass); 481 DrawRenderPass(render_pass);
490 482
491 bool first_request = true; 483 bool first_request = true;
492 for (auto& copy_request : render_pass->copy_requests) { 484 for (auto& copy_request : render_pass->copy_requests) {
493 // Doing a readback is destructive of our state on Mac, so make sure 485 // Doing a readback is destructive of our state on Mac, so make sure
494 // we restore the state between readbacks. http://crbug.com/99393. 486 // we restore the state between readbacks. http://crbug.com/99393.
495 if (!first_request) 487 if (!first_request)
496 UseRenderPass(frame, render_pass); 488 UseRenderPass(render_pass);
497 CopyCurrentRenderPassToBitmap(frame, std::move(copy_request)); 489 CopyCurrentRenderPassToBitmap(std::move(copy_request));
498 first_request = false; 490 first_request = false;
499 } 491 }
500 } 492 }
501 493
502 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, 494 void DirectRenderer::DrawRenderPass(const RenderPass* render_pass) {
503 const RenderPass* render_pass) {
504 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); 495 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass");
505 if (!UseRenderPass(frame, render_pass)) 496 if (!UseRenderPass(render_pass))
506 return; 497 return;
507 498
508 const gfx::Rect surface_rect_in_draw_space = 499 const gfx::Rect surface_rect_in_draw_space = OutputSurfaceRectInDrawSpace();
509 OutputSurfaceRectInDrawSpace(frame);
510 gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space; 500 gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space;
511 501
512 if (frame->current_render_pass == frame->root_render_pass) { 502 if (current_frame_->current_render_pass == current_frame_->root_render_pass) {
513 render_pass_scissor_in_draw_space.Intersect( 503 render_pass_scissor_in_draw_space.Intersect(
514 DeviceViewportRectInDrawSpace(frame)); 504 DeviceViewportRectInDrawSpace());
515 } 505 }
516 506
517 if (use_partial_swap_) { 507 if (use_partial_swap_) {
518 render_pass_scissor_in_draw_space.Intersect( 508 render_pass_scissor_in_draw_space.Intersect(
519 ComputeScissorRectForRenderPass(frame)); 509 current_frame_->ComputeScissorRectForRenderPass());
520 } 510 }
521 511
522 bool render_pass_is_clipped = 512 bool render_pass_is_clipped =
523 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); 513 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space);
524 bool is_root_render_pass = 514 bool is_root_render_pass =
525 frame->current_render_pass == frame->root_render_pass; 515 current_frame_->current_render_pass == current_frame_->root_render_pass;
526 bool has_external_stencil_test = 516 bool has_external_stencil_test =
527 is_root_render_pass && output_surface_->HasExternalStencilTest(); 517 is_root_render_pass && output_surface_->HasExternalStencilTest();
528 bool should_clear_surface = 518 bool should_clear_surface =
529 !has_external_stencil_test && 519 !has_external_stencil_test &&
530 (!is_root_render_pass || settings_->should_clear_root_render_pass); 520 (!is_root_render_pass || settings_->should_clear_root_render_pass);
531 521
532 // If |has_external_stencil_test| we can't discard or clear. Make sure we 522 // If |has_external_stencil_test| we can't discard or clear. Make sure we
533 // don't need to. 523 // don't need to.
534 DCHECK(!has_external_stencil_test || 524 DCHECK(!has_external_stencil_test ||
535 !frame->current_render_pass->has_transparent_background); 525 !current_frame_->current_render_pass->has_transparent_background);
536 526
537 SurfaceInitializationMode mode; 527 SurfaceInitializationMode mode;
538 if (should_clear_surface && render_pass_is_clipped) { 528 if (should_clear_surface && render_pass_is_clipped) {
539 mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR; 529 mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR;
540 } else if (should_clear_surface) { 530 } else if (should_clear_surface) {
541 mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR; 531 mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR;
542 } else { 532 } else {
543 mode = SURFACE_INITIALIZATION_MODE_PRESERVE; 533 mode = SURFACE_INITIALIZATION_MODE_PRESERVE;
544 } 534 }
545 535
546 PrepareSurfaceForPass( 536 PrepareSurfaceForPass(
547 frame, mode, 537 mode, MoveFromDrawToWindowSpace(render_pass_scissor_in_draw_space));
548 MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space));
549 538
550 const QuadList& quad_list = render_pass->quad_list; 539 const QuadList& quad_list = render_pass->quad_list;
551 std::deque<std::unique_ptr<DrawPolygon>> poly_list; 540 std::deque<std::unique_ptr<DrawPolygon>> poly_list;
552 541
553 int next_polygon_id = 0; 542 int next_polygon_id = 0;
554 int last_sorting_context_id = 0; 543 int last_sorting_context_id = 0;
555 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); 544 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd();
556 ++it) { 545 ++it) {
557 const DrawQuad& quad = **it; 546 const DrawQuad& quad = **it;
558 547
559 if (render_pass_is_clipped && 548 if (render_pass_is_clipped &&
560 ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) { 549 ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) {
561 continue; 550 continue;
562 } 551 }
563 552
564 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) { 553 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) {
565 last_sorting_context_id = quad.shared_quad_state->sorting_context_id; 554 last_sorting_context_id = quad.shared_quad_state->sorting_context_id;
566 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, 555 FlushPolygons(&poly_list, render_pass_scissor_in_draw_space,
567 render_pass_is_clipped); 556 render_pass_is_clipped);
568 } 557 }
569 558
570 // This layer is in a 3D sorting context so we add it to the list of 559 // This layer is in a 3D sorting context so we add it to the list of
571 // polygons to go into the BSP tree. 560 // polygons to go into the BSP tree.
572 if (quad.shared_quad_state->sorting_context_id != 0) { 561 if (quad.shared_quad_state->sorting_context_id != 0) {
573 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon( 562 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon(
574 *it, gfx::RectF(quad.visible_rect), 563 *it, gfx::RectF(quad.visible_rect),
575 quad.shared_quad_state->quad_to_target_transform, next_polygon_id++)); 564 quad.shared_quad_state->quad_to_target_transform, next_polygon_id++));
576 if (new_polygon->points().size() > 2u) { 565 if (new_polygon->points().size() > 2u) {
577 poly_list.push_back(std::move(new_polygon)); 566 poly_list.push_back(std::move(new_polygon));
578 } 567 }
579 continue; 568 continue;
580 } 569 }
581 570
582 // We are not in a 3d sorting context, so we should draw the quad normally. 571 // We are not in a 3d sorting context, so we should draw the quad normally.
583 SetScissorStateForQuad(frame, quad, render_pass_scissor_in_draw_space, 572 SetScissorStateForQuad(quad, render_pass_scissor_in_draw_space,
584 render_pass_is_clipped); 573 render_pass_is_clipped);
585 574
586 DoDrawQuad(frame, &quad, nullptr); 575 DoDrawQuad(&quad, nullptr);
587 } 576 }
588 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, 577 FlushPolygons(&poly_list, render_pass_scissor_in_draw_space,
589 render_pass_is_clipped); 578 render_pass_is_clipped);
590 FinishDrawingQuadList(); 579 FinishDrawingQuadList();
591 } 580 }
592 581
593 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, 582 bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) {
594 const RenderPass* render_pass) { 583 current_frame_->current_render_pass = render_pass;
595 frame->current_render_pass = render_pass; 584 current_frame_->current_texture = NULL;
596 frame->current_texture = NULL; 585 if (render_pass == current_frame_->root_render_pass) {
597 if (render_pass == frame->root_render_pass) { 586 BindFramebufferToOutputSurface();
598 BindFramebufferToOutputSurface(frame); 587 InitializeViewport(current_frame_, render_pass->output_rect,
599 InitializeViewport(frame, render_pass->output_rect, 588 gfx::Rect(current_frame_->device_viewport_size),
600 gfx::Rect(frame->device_viewport_size), 589 current_frame_->device_viewport_size);
601 frame->device_viewport_size);
602 return true; 590 return true;
603 } 591 }
604 592
605 ScopedResource* texture = render_pass_textures_[render_pass->id].get(); 593 ScopedResource* texture = render_pass_textures_[render_pass->id].get();
606 DCHECK(texture); 594 DCHECK(texture);
607 595
608 gfx::Size size = RenderPassTextureSize(render_pass); 596 gfx::Size size = RenderPassTextureSize(render_pass);
609 size.Enlarge(enlarge_pass_texture_amount_.width(), 597 size.Enlarge(enlarge_pass_texture_amount_.width(),
610 enlarge_pass_texture_amount_.height()); 598 enlarge_pass_texture_amount_.height());
611 if (!texture->id()) { 599 if (!texture->id()) {
612 texture->Allocate(size, 600 texture->Allocate(size,
613 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, 601 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
614 BackbufferFormat(), frame->device_color_space); 602 BackbufferFormat(), current_frame_->device_color_space);
615 } 603 }
616 DCHECK(texture->id()); 604 DCHECK(texture->id());
617 605
618 if (BindFramebufferToTexture(frame, texture)) { 606 if (BindFramebufferToTexture(texture)) {
619 InitializeViewport(frame, render_pass->output_rect, 607 InitializeViewport(current_frame_, render_pass->output_rect,
620 gfx::Rect(render_pass->output_rect.size()), 608 gfx::Rect(render_pass->output_rect.size()),
621 texture->size()); 609 texture->size());
622 return true; 610 return true;
623 } 611 }
624 612
625 return false; 613 return false;
626 } 614 }
627 615
628 bool DirectRenderer::HasAllocatedResourcesForTesting(int render_pass_id) const { 616 bool DirectRenderer::HasAllocatedResourcesForTesting(int render_pass_id) const {
629 auto iter = render_pass_textures_.find(render_pass_id); 617 auto iter = render_pass_textures_.find(render_pass_id);
630 return iter != render_pass_textures_.end() && iter->second->id(); 618 return iter != render_pass_textures_.end() && iter->second->id();
631 } 619 }
632 620
633 // static 621 // static
634 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { 622 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) {
635 return render_pass->output_rect.size(); 623 return render_pass->output_rect.size();
636 } 624 }
637 625
638 } // namespace cc 626 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/direct_renderer.h ('k') | cc/output/gl_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698