| // Copyright 2011 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "cc/quads/render_pass.h" | 
 |  | 
 | #include <algorithm> | 
 |  | 
 | #include "base/debug/trace_event_argument.h" | 
 | #include "base/values.h" | 
 | #include "cc/base/math_util.h" | 
 | #include "cc/debug/traced_value.h" | 
 | #include "cc/output/copy_output_request.h" | 
 | #include "cc/quads/checkerboard_draw_quad.h" | 
 | #include "cc/quads/debug_border_draw_quad.h" | 
 | #include "cc/quads/draw_quad.h" | 
 | #include "cc/quads/io_surface_draw_quad.h" | 
 | #include "cc/quads/largest_draw_quad.h" | 
 | #include "cc/quads/picture_draw_quad.h" | 
 | #include "cc/quads/render_pass_draw_quad.h" | 
 | #include "cc/quads/shared_quad_state.h" | 
 | #include "cc/quads/solid_color_draw_quad.h" | 
 | #include "cc/quads/stream_video_draw_quad.h" | 
 | #include "cc/quads/surface_draw_quad.h" | 
 | #include "cc/quads/texture_draw_quad.h" | 
 | #include "cc/quads/tile_draw_quad.h" | 
 | #include "cc/quads/yuv_video_draw_quad.h" | 
 |  | 
 | namespace { | 
 | const size_t kDefaultNumSharedQuadStatesToReserve = 32; | 
 | const size_t kDefaultNumQuadsToReserve = 128; | 
 | } | 
 |  | 
 | namespace cc { | 
 |  | 
 | QuadList::QuadList(size_t default_size_to_reserve) | 
 |     : ListContainer<DrawQuad>(LargestDrawQuadSize(), default_size_to_reserve) { | 
 | } | 
 |  | 
 | scoped_ptr<RenderPass> RenderPass::Create() { | 
 |   return make_scoped_ptr(new RenderPass()); | 
 | } | 
 |  | 
 | scoped_ptr<RenderPass> RenderPass::Create(size_t num_layers) { | 
 |   return make_scoped_ptr(new RenderPass(num_layers)); | 
 | } | 
 |  | 
 | scoped_ptr<RenderPass> RenderPass::Create(size_t shared_quad_state_list_size, | 
 |                                           size_t quad_list_size) { | 
 |   return make_scoped_ptr( | 
 |       new RenderPass(shared_quad_state_list_size, quad_list_size)); | 
 | } | 
 |  | 
 | RenderPass::RenderPass() | 
 |     : id(RenderPassId(-1, -1)), | 
 |       has_transparent_background(true), | 
 |       quad_list(kDefaultNumQuadsToReserve), | 
 |       shared_quad_state_list(sizeof(SharedQuadState), | 
 |                              kDefaultNumSharedQuadStatesToReserve) { | 
 | } | 
 |  | 
 | // Each layer usually produces one shared quad state, so the number of layers | 
 | // is a good hint for what to reserve here. | 
 | RenderPass::RenderPass(size_t num_layers) | 
 |     : id(RenderPassId(-1, -1)), | 
 |       has_transparent_background(true), | 
 |       quad_list(kDefaultNumQuadsToReserve), | 
 |       shared_quad_state_list(sizeof(SharedQuadState), num_layers) { | 
 | } | 
 |  | 
 | RenderPass::RenderPass(size_t shared_quad_state_list_size, | 
 |                        size_t quad_list_size) | 
 |     : id(RenderPassId(-1, -1)), | 
 |       has_transparent_background(true), | 
 |       quad_list(quad_list_size), | 
 |       shared_quad_state_list(sizeof(SharedQuadState), | 
 |                              shared_quad_state_list_size) { | 
 | } | 
 |  | 
 | RenderPass::~RenderPass() { | 
 |   TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 
 |       TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), | 
 |       "cc::RenderPass", id.AsTracingId()); | 
 | } | 
 |  | 
 | scoped_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const { | 
 |   scoped_ptr<RenderPass> copy_pass( | 
 |       Create(shared_quad_state_list.size(), quad_list.size())); | 
 |   copy_pass->SetAll(new_id, | 
 |                     output_rect, | 
 |                     damage_rect, | 
 |                     transform_to_root_target, | 
 |                     has_transparent_background); | 
 |   return copy_pass.Pass(); | 
 | } | 
 |  | 
 | // static | 
 | void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in, | 
 |                          ScopedPtrVector<RenderPass>* out) { | 
 |   for (size_t i = 0; i < in.size(); ++i) { | 
 |     RenderPass* source = in[i]; | 
 |  | 
 |     // Since we can't copy these, it's wrong to use CopyAll in a situation where | 
 |     // you may have copy_requests present. | 
 |     DCHECK_EQ(source->copy_requests.size(), 0u); | 
 |  | 
 |     scoped_ptr<RenderPass> copy_pass(Create( | 
 |         source->shared_quad_state_list.size(), source->quad_list.size())); | 
 |     copy_pass->SetAll(source->id, | 
 |                       source->output_rect, | 
 |                       source->damage_rect, | 
 |                       source->transform_to_root_target, | 
 |                       source->has_transparent_background); | 
 |     for (const auto& shared_quad_state : source->shared_quad_state_list) { | 
 |       SharedQuadState* copy_shared_quad_state = | 
 |           copy_pass->CreateAndAppendSharedQuadState(); | 
 |       copy_shared_quad_state->CopyFrom(shared_quad_state); | 
 |     } | 
 |     SharedQuadStateList::Iterator sqs_iter = | 
 |         source->shared_quad_state_list.begin(); | 
 |     SharedQuadStateList::Iterator copy_sqs_iter = | 
 |         copy_pass->shared_quad_state_list.begin(); | 
 |     for (const auto& quad : source->quad_list) { | 
 |       while (quad->shared_quad_state != *sqs_iter) { | 
 |         ++sqs_iter; | 
 |         ++copy_sqs_iter; | 
 |         DCHECK(sqs_iter != source->shared_quad_state_list.end()); | 
 |       } | 
 |       DCHECK(quad->shared_quad_state == *sqs_iter); | 
 |  | 
 |       SharedQuadState* copy_shared_quad_state = *copy_sqs_iter; | 
 |  | 
 |       if (quad->material == DrawQuad::RENDER_PASS) { | 
 |         const RenderPassDrawQuad* pass_quad = | 
 |             RenderPassDrawQuad::MaterialCast(quad); | 
 |         copy_pass->CopyFromAndAppendRenderPassDrawQuad( | 
 |             pass_quad, copy_shared_quad_state, pass_quad->render_pass_id); | 
 |       } else { | 
 |         copy_pass->CopyFromAndAppendDrawQuad(quad, copy_shared_quad_state); | 
 |       } | 
 |     } | 
 |     out->push_back(copy_pass.Pass()); | 
 |   } | 
 | } | 
 |  | 
 | void RenderPass::SetNew(RenderPassId id, | 
 |                         const gfx::Rect& output_rect, | 
 |                         const gfx::Rect& damage_rect, | 
 |                         const gfx::Transform& transform_to_root_target) { | 
 |   DCHECK_GT(id.layer_id, 0); | 
 |   DCHECK_GE(id.index, 0); | 
 |   DCHECK(damage_rect.IsEmpty() || output_rect.Contains(damage_rect)) | 
 |       << "damage_rect: " << damage_rect.ToString() | 
 |       << " output_rect: " << output_rect.ToString(); | 
 |  | 
 |   this->id = id; | 
 |   this->output_rect = output_rect; | 
 |   this->damage_rect = damage_rect; | 
 |   this->transform_to_root_target = transform_to_root_target; | 
 |  | 
 |   DCHECK(quad_list.empty()); | 
 |   DCHECK(shared_quad_state_list.empty()); | 
 | } | 
 |  | 
 | void RenderPass::SetAll(RenderPassId id, | 
 |                         const gfx::Rect& output_rect, | 
 |                         const gfx::Rect& damage_rect, | 
 |                         const gfx::Transform& transform_to_root_target, | 
 |                         bool has_transparent_background) { | 
 |   DCHECK_GT(id.layer_id, 0); | 
 |   DCHECK_GE(id.index, 0); | 
 |  | 
 |   this->id = id; | 
 |   this->output_rect = output_rect; | 
 |   this->damage_rect = damage_rect; | 
 |   this->transform_to_root_target = transform_to_root_target; | 
 |   this->has_transparent_background = has_transparent_background; | 
 |  | 
 |   DCHECK(quad_list.empty()); | 
 |   DCHECK(shared_quad_state_list.empty()); | 
 | } | 
 |  | 
 | void RenderPass::AsValueInto(base::debug::TracedValue* value) const { | 
 |   value->BeginArray("output_rect"); | 
 |   MathUtil::AddToTracedValue(output_rect, value); | 
 |   value->EndArray(); | 
 |  | 
 |   value->BeginArray("damage_rect"); | 
 |   MathUtil::AddToTracedValue(damage_rect, value); | 
 |   value->EndArray(); | 
 |  | 
 |   value->SetBoolean("has_transparent_background", has_transparent_background); | 
 |   value->SetInteger("copy_requests", copy_requests.size()); | 
 |  | 
 |   value->BeginArray("shared_quad_state_list"); | 
 |   for (const auto& shared_quad_state : shared_quad_state_list) { | 
 |     value->BeginDictionary(); | 
 |     shared_quad_state->AsValueInto(value); | 
 |     value->EndDictionary(); | 
 |   } | 
 |   value->EndArray(); | 
 |  | 
 |   value->BeginArray("quad_list"); | 
 |   for (const auto& quad : quad_list) { | 
 |     value->BeginDictionary(); | 
 |     quad->AsValueInto(value); | 
 |     value->EndDictionary(); | 
 |   } | 
 |   value->EndArray(); | 
 |  | 
 |   TracedValue::MakeDictIntoImplicitSnapshotWithCategory( | 
 |       TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), | 
 |       value, | 
 |       "cc::RenderPass", | 
 |       id.AsTracingId()); | 
 | } | 
 |  | 
 | SharedQuadState* RenderPass::CreateAndAppendSharedQuadState() { | 
 |   return shared_quad_state_list.AllocateAndConstruct<SharedQuadState>(); | 
 | } | 
 |  | 
 | RenderPassDrawQuad* RenderPass::CopyFromAndAppendRenderPassDrawQuad( | 
 |     const RenderPassDrawQuad* quad, | 
 |     const SharedQuadState* shared_quad_state, | 
 |     RenderPassId render_pass_id) { | 
 |   RenderPassDrawQuad* copy_quad = | 
 |       CopyFromAndAppendTypedDrawQuad<RenderPassDrawQuad>(quad); | 
 |   copy_quad->shared_quad_state = shared_quad_state; | 
 |   copy_quad->render_pass_id = render_pass_id; | 
 |   return copy_quad; | 
 | } | 
 |  | 
 | DrawQuad* RenderPass::CopyFromAndAppendDrawQuad( | 
 |     const DrawQuad* quad, | 
 |     const SharedQuadState* shared_quad_state) { | 
 |   switch (quad->material) { | 
 |     case DrawQuad::CHECKERBOARD: | 
 |       CopyFromAndAppendTypedDrawQuad<CheckerboardDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::DEBUG_BORDER: | 
 |       CopyFromAndAppendTypedDrawQuad<DebugBorderDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::IO_SURFACE_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<IOSurfaceDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::PICTURE_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<PictureDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::TEXTURE_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<TextureDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::SOLID_COLOR: | 
 |       CopyFromAndAppendTypedDrawQuad<SolidColorDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::TILED_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<TileDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::STREAM_VIDEO_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<StreamVideoDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::SURFACE_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<SurfaceDrawQuad>(quad); | 
 |       break; | 
 |     case DrawQuad::YUV_VIDEO_CONTENT: | 
 |       CopyFromAndAppendTypedDrawQuad<YUVVideoDrawQuad>(quad); | 
 |       break; | 
 |     // RenderPass quads need to use specific CopyFrom function. | 
 |     case DrawQuad::RENDER_PASS: | 
 |     case DrawQuad::INVALID: | 
 |       LOG(FATAL) << "Invalid DrawQuad material " << quad->material; | 
 |       break; | 
 |   } | 
 |   quad_list.back()->shared_quad_state = shared_quad_state; | 
 |   return quad_list.back(); | 
 | } | 
 |  | 
 | }  // namespace cc |