1 // Copyright 2011 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/quads/render_pass.h" 6 7 #include "base/values.h" 8 #include "cc/base/math_util.h" 9 #include "cc/debug/traced_value.h" 10 #include "cc/output/copy_output_request.h" 11 #include "cc/quads/draw_quad.h" 12 #include "cc/quads/render_pass_draw_quad.h" 13 #include "cc/quads/shared_quad_state.h" 14 15 namespace { 16 const size_t kDefaultNumSharedQuadStatesToReserve = 32; 17 const size_t kDefaultNumQuadsToReserve = 128; 18 } 19 20 namespace cc { 21 22 void* RenderPass::Id::AsTracingId() const { 23 COMPILE_ASSERT(sizeof(size_t) <= sizeof(void*), // NOLINT(runtime/sizeof) 24 size_t_bigger_than_pointer); 25 return reinterpret_cast<void*>(base::HashPair(layer_id, index)); 26 } 27 28 scoped_ptr<RenderPass> RenderPass::Create() { 29 return make_scoped_ptr(new RenderPass()); 30 } 31 32 scoped_ptr<RenderPass> RenderPass::Create(size_t num_layers) { 33 return make_scoped_ptr(new RenderPass(num_layers)); 34 } 35 36 RenderPass::RenderPass() 37 : id(Id(-1, -1)), 38 has_transparent_background(true) { 39 shared_quad_state_list.reserve(kDefaultNumSharedQuadStatesToReserve); 40 quad_list.reserve(kDefaultNumQuadsToReserve); 41 } 42 43 RenderPass::RenderPass(size_t num_layers) 44 : id(Id(-1, -1)), 45 has_transparent_background(true) { 46 // Each layer usually produces one shared quad state, so the number of layers 47 // is a good hint for what to reserve here. 48 shared_quad_state_list.reserve(num_layers); 49 quad_list.reserve(kDefaultNumQuadsToReserve); 50 } 51 52 RenderPass::~RenderPass() { 53 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 54 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), 55 "cc::RenderPass", id.AsTracingId()); 56 } 57 58 scoped_ptr<RenderPass> RenderPass::Copy(Id new_id) const { 59 scoped_ptr<RenderPass> copy_pass(Create()); 60 copy_pass->SetAll(new_id, 61 output_rect, 62 damage_rect, 63 transform_to_root_target, 64 has_transparent_background); 65 return copy_pass.Pass(); 66 } 67 68 // static 69 void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in, 70 ScopedPtrVector<RenderPass>* out) { 71 for (size_t i = 0; i < in.size(); ++i) { 72 RenderPass* source = in[i]; 73 74 // Since we can't copy these, it's wrong to use CopyAll in a situation where 75 // you may have copy_requests present. 76 DCHECK_EQ(source->copy_requests.size(), 0u); 77 78 scoped_ptr<RenderPass> copy_pass(Create()); 79 copy_pass->SetAll(source->id, 80 source->output_rect, 81 source->damage_rect, 82 source->transform_to_root_target, 83 source->has_transparent_background); 84 for (size_t i = 0; i < source->shared_quad_state_list.size(); ++i) { 85 copy_pass->shared_quad_state_list.push_back( 86 source->shared_quad_state_list[i]->Copy()); 87 } 88 for (size_t i = 0, sqs_i = 0; i < source->quad_list.size(); ++i) { 89 while (source->quad_list[i]->shared_quad_state != 90 source->shared_quad_state_list[sqs_i]) { 91 ++sqs_i; 92 DCHECK_LT(sqs_i, source->shared_quad_state_list.size()); 93 } 94 DCHECK(source->quad_list[i]->shared_quad_state == 95 source->shared_quad_state_list[sqs_i]); 96 97 DrawQuad* quad = source->quad_list[i]; 98 99 if (quad->material == DrawQuad::RENDER_PASS) { 100 const RenderPassDrawQuad* pass_quad = 101 RenderPassDrawQuad::MaterialCast(quad); 102 copy_pass->quad_list.push_back( 103 pass_quad->Copy(copy_pass->shared_quad_state_list[sqs_i], 104 pass_quad->render_pass_id).PassAs<DrawQuad>()); 105 } else { 106 copy_pass->quad_list.push_back(source->quad_list[i]->Copy( 107 copy_pass->shared_quad_state_list[sqs_i])); 108 } 109 } 110 out->push_back(copy_pass.Pass()); 111 } 112 } 113 114 void RenderPass::SetNew(Id id, 115 gfx::Rect output_rect, 116 gfx::RectF damage_rect, 117 const gfx::Transform& transform_to_root_target) { 118 DCHECK_GT(id.layer_id, 0); 119 DCHECK_GE(id.index, 0); 120 121 this->id = id; 122 this->output_rect = output_rect; 123 this->damage_rect = damage_rect; 124 this->transform_to_root_target = transform_to_root_target; 125 126 DCHECK(quad_list.empty()); 127 DCHECK(shared_quad_state_list.empty()); 128 } 129 130 void RenderPass::SetAll(Id id, 131 gfx::Rect output_rect, 132 gfx::RectF damage_rect, 133 const gfx::Transform& transform_to_root_target, 134 bool has_transparent_background) { 135 DCHECK_GT(id.layer_id, 0); 136 DCHECK_GE(id.index, 0); 137 138 this->id = id; 139 this->output_rect = output_rect; 140 this->damage_rect = damage_rect; 141 this->transform_to_root_target = transform_to_root_target; 142 this->has_transparent_background = has_transparent_background; 143 144 DCHECK(quad_list.empty()); 145 DCHECK(shared_quad_state_list.empty()); 146 } 147 148 scoped_ptr<base::Value> RenderPass::AsValue() const { 149 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 150 value->Set("output_rect", MathUtil::AsValue(output_rect).release()); 151 value->Set("damage_rect", MathUtil::AsValue(damage_rect).release()); 152 value->SetBoolean("has_transparent_background", has_transparent_background); 153 value->SetInteger("copy_requests", copy_requests.size()); 154 scoped_ptr<base::ListValue> shared_states_value(new base::ListValue()); 155 for (size_t i = 0; i < shared_quad_state_list.size(); ++i) { 156 shared_states_value->Append(shared_quad_state_list[i]->AsValue().release()); 157 } 158 value->Set("shared_quad_state_list", shared_states_value.release()); 159 scoped_ptr<base::ListValue> quad_list_value(new base::ListValue()); 160 for (size_t i = 0; i < quad_list.size(); ++i) { 161 quad_list_value->Append(quad_list[i]->AsValue().release()); 162 } 163 value->Set("quad_list", quad_list_value.release()); 164 165 TracedValue::MakeDictIntoImplicitSnapshotWithCategory( 166 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), 167 value.get(), "cc::RenderPass", id.AsTracingId()); 168 return value.PassAs<base::Value>(); 169 } 170 171 } // namespace cc 172