Home | History | Annotate | Download | only in quads
      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/debug/trace_event_argument.h"
      8 #include "base/values.h"
      9 #include "cc/base/math_util.h"
     10 #include "cc/debug/traced_value.h"
     11 #include "cc/output/copy_output_request.h"
     12 #include "cc/quads/checkerboard_draw_quad.h"
     13 #include "cc/quads/debug_border_draw_quad.h"
     14 #include "cc/quads/draw_quad.h"
     15 #include "cc/quads/io_surface_draw_quad.h"
     16 #include "cc/quads/largest_draw_quad.h"
     17 #include "cc/quads/picture_draw_quad.h"
     18 #include "cc/quads/render_pass_draw_quad.h"
     19 #include "cc/quads/shared_quad_state.h"
     20 #include "cc/quads/solid_color_draw_quad.h"
     21 #include "cc/quads/stream_video_draw_quad.h"
     22 #include "cc/quads/surface_draw_quad.h"
     23 #include "cc/quads/texture_draw_quad.h"
     24 #include "cc/quads/tile_draw_quad.h"
     25 #include "cc/quads/yuv_video_draw_quad.h"
     26 
     27 namespace {
     28 const size_t kDefaultNumSharedQuadStatesToReserve = 32;
     29 const size_t kDefaultNumQuadsToReserve = 128;
     30 }
     31 
     32 namespace cc {
     33 
     34 QuadList::QuadList(size_t default_size_to_reserve)
     35     : ListContainer<DrawQuad>(sizeof(kLargestDrawQuad),
     36                               default_size_to_reserve) {
     37 }
     38 
     39 scoped_ptr<RenderPass> RenderPass::Create() {
     40   return make_scoped_ptr(new RenderPass());
     41 }
     42 
     43 scoped_ptr<RenderPass> RenderPass::Create(size_t num_layers) {
     44   return make_scoped_ptr(new RenderPass(num_layers));
     45 }
     46 
     47 RenderPass::RenderPass()
     48     : id(RenderPassId(-1, -1)),
     49       has_transparent_background(true),
     50       quad_list(kDefaultNumQuadsToReserve) {
     51   shared_quad_state_list.reserve(kDefaultNumSharedQuadStatesToReserve);
     52 }
     53 
     54 RenderPass::RenderPass(size_t num_layers)
     55     : id(RenderPassId(-1, -1)),
     56       has_transparent_background(true),
     57       quad_list(kDefaultNumQuadsToReserve) {
     58   // Each layer usually produces one shared quad state, so the number of layers
     59   // is a good hint for what to reserve here.
     60   shared_quad_state_list.reserve(num_layers);
     61 }
     62 
     63 RenderPass::~RenderPass() {
     64   TRACE_EVENT_OBJECT_DELETED_WITH_ID(
     65       TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
     66       "cc::RenderPass", id.AsTracingId());
     67 }
     68 
     69 scoped_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const {
     70   scoped_ptr<RenderPass> copy_pass(Create());
     71   copy_pass->SetAll(new_id,
     72                     output_rect,
     73                     damage_rect,
     74                     transform_to_root_target,
     75                     has_transparent_background);
     76   return copy_pass.Pass();
     77 }
     78 
     79 // static
     80 void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in,
     81                          ScopedPtrVector<RenderPass>* out) {
     82   for (size_t i = 0; i < in.size(); ++i) {
     83     RenderPass* source = in[i];
     84 
     85     // Since we can't copy these, it's wrong to use CopyAll in a situation where
     86     // you may have copy_requests present.
     87     DCHECK_EQ(source->copy_requests.size(), 0u);
     88 
     89     scoped_ptr<RenderPass> copy_pass(Create());
     90     copy_pass->SetAll(source->id,
     91                       source->output_rect,
     92                       source->damage_rect,
     93                       source->transform_to_root_target,
     94                       source->has_transparent_background);
     95     for (size_t i = 0; i < source->shared_quad_state_list.size(); ++i) {
     96       SharedQuadState* copy_shared_quad_state =
     97           copy_pass->CreateAndAppendSharedQuadState();
     98       copy_shared_quad_state->CopyFrom(source->shared_quad_state_list[i]);
     99     }
    100     size_t sqs_i = 0;
    101     for (QuadList::Iterator iter = source->quad_list.begin();
    102          iter != source->quad_list.end();
    103          ++iter) {
    104       while (iter->shared_quad_state != source->shared_quad_state_list[sqs_i]) {
    105         ++sqs_i;
    106         DCHECK_LT(sqs_i, source->shared_quad_state_list.size());
    107       }
    108       DCHECK(iter->shared_quad_state == source->shared_quad_state_list[sqs_i]);
    109 
    110       DrawQuad* quad = &*iter;
    111 
    112       if (quad->material == DrawQuad::RENDER_PASS) {
    113         const RenderPassDrawQuad* pass_quad =
    114             RenderPassDrawQuad::MaterialCast(quad);
    115         copy_pass->CopyFromAndAppendRenderPassDrawQuad(
    116             pass_quad,
    117             copy_pass->shared_quad_state_list[sqs_i],
    118             pass_quad->render_pass_id);
    119       } else {
    120         copy_pass->CopyFromAndAppendDrawQuad(
    121             quad, copy_pass->shared_quad_state_list[sqs_i]);
    122       }
    123     }
    124     out->push_back(copy_pass.Pass());
    125   }
    126 }
    127 
    128 void RenderPass::SetNew(RenderPassId id,
    129                         const gfx::Rect& output_rect,
    130                         const gfx::Rect& damage_rect,
    131                         const gfx::Transform& transform_to_root_target) {
    132   DCHECK_GT(id.layer_id, 0);
    133   DCHECK_GE(id.index, 0);
    134   DCHECK(damage_rect.IsEmpty() || output_rect.Contains(damage_rect))
    135       << "damage_rect: " << damage_rect.ToString()
    136       << " output_rect: " << output_rect.ToString();
    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 
    143   DCHECK(quad_list.empty());
    144   DCHECK(shared_quad_state_list.empty());
    145 }
    146 
    147 void RenderPass::SetAll(RenderPassId id,
    148                         const gfx::Rect& output_rect,
    149                         const gfx::Rect& damage_rect,
    150                         const gfx::Transform& transform_to_root_target,
    151                         bool has_transparent_background) {
    152   DCHECK_GT(id.layer_id, 0);
    153   DCHECK_GE(id.index, 0);
    154 
    155   this->id = id;
    156   this->output_rect = output_rect;
    157   this->damage_rect = damage_rect;
    158   this->transform_to_root_target = transform_to_root_target;
    159   this->has_transparent_background = has_transparent_background;
    160 
    161   DCHECK(quad_list.empty());
    162   DCHECK(shared_quad_state_list.empty());
    163 }
    164 
    165 void RenderPass::AsValueInto(base::debug::TracedValue* value) const {
    166   value->BeginArray("output_rect");
    167   MathUtil::AddToTracedValue(output_rect, value);
    168   value->EndArray();
    169 
    170   value->BeginArray("damage_rect");
    171   MathUtil::AddToTracedValue(damage_rect, value);
    172   value->EndArray();
    173 
    174   value->SetBoolean("has_transparent_background", has_transparent_background);
    175   value->SetInteger("copy_requests", copy_requests.size());
    176 
    177   value->BeginArray("shared_quad_state_list");
    178   for (size_t i = 0; i < shared_quad_state_list.size(); ++i) {
    179     value->BeginDictionary();
    180     shared_quad_state_list[i]->AsValueInto(value);
    181     value->EndDictionary();
    182   }
    183   value->EndArray();
    184 
    185   value->BeginArray("quad_list");
    186   for (QuadList::ConstIterator iter = quad_list.begin();
    187        iter != quad_list.end();
    188        ++iter) {
    189     value->BeginDictionary();
    190     iter->AsValueInto(value);
    191     value->EndDictionary();
    192   }
    193   value->EndArray();
    194 
    195   TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
    196       TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
    197       value,
    198       "cc::RenderPass",
    199       id.AsTracingId());
    200 }
    201 
    202 SharedQuadState* RenderPass::CreateAndAppendSharedQuadState() {
    203   shared_quad_state_list.push_back(make_scoped_ptr(new SharedQuadState));
    204   return shared_quad_state_list.back();
    205 }
    206 
    207 RenderPassDrawQuad* RenderPass::CopyFromAndAppendRenderPassDrawQuad(
    208     const RenderPassDrawQuad* quad,
    209     const SharedQuadState* shared_quad_state,
    210     RenderPassId render_pass_id) {
    211   RenderPassDrawQuad* copy_quad =
    212       CopyFromAndAppendTypedDrawQuad<RenderPassDrawQuad>(quad);
    213   copy_quad->shared_quad_state = shared_quad_state;
    214   copy_quad->render_pass_id = render_pass_id;
    215   return copy_quad;
    216 }
    217 
    218 DrawQuad* RenderPass::CopyFromAndAppendDrawQuad(
    219     const DrawQuad* quad,
    220     const SharedQuadState* shared_quad_state) {
    221   switch (quad->material) {
    222     case DrawQuad::CHECKERBOARD:
    223       CopyFromAndAppendTypedDrawQuad<CheckerboardDrawQuad>(quad);
    224       break;
    225     case DrawQuad::DEBUG_BORDER:
    226       CopyFromAndAppendTypedDrawQuad<DebugBorderDrawQuad>(quad);
    227       break;
    228     case DrawQuad::IO_SURFACE_CONTENT:
    229       CopyFromAndAppendTypedDrawQuad<IOSurfaceDrawQuad>(quad);
    230       break;
    231     case DrawQuad::PICTURE_CONTENT:
    232       CopyFromAndAppendTypedDrawQuad<PictureDrawQuad>(quad);
    233       break;
    234     case DrawQuad::TEXTURE_CONTENT:
    235       CopyFromAndAppendTypedDrawQuad<TextureDrawQuad>(quad);
    236       break;
    237     case DrawQuad::SOLID_COLOR:
    238       CopyFromAndAppendTypedDrawQuad<SolidColorDrawQuad>(quad);
    239       break;
    240     case DrawQuad::TILED_CONTENT:
    241       CopyFromAndAppendTypedDrawQuad<TileDrawQuad>(quad);
    242       break;
    243     case DrawQuad::STREAM_VIDEO_CONTENT:
    244       CopyFromAndAppendTypedDrawQuad<StreamVideoDrawQuad>(quad);
    245       break;
    246     case DrawQuad::SURFACE_CONTENT:
    247       CopyFromAndAppendTypedDrawQuad<SurfaceDrawQuad>(quad);
    248       break;
    249     case DrawQuad::YUV_VIDEO_CONTENT:
    250       CopyFromAndAppendTypedDrawQuad<YUVVideoDrawQuad>(quad);
    251       break;
    252     // RenderPass quads need to use specific CopyFrom function.
    253     case DrawQuad::RENDER_PASS:
    254     case DrawQuad::INVALID:
    255       LOG(FATAL) << "Invalid DrawQuad material " << quad->material;
    256       break;
    257   }
    258   quad_list.back()->shared_quad_state = shared_quad_state;
    259   return quad_list.back();
    260 }
    261 
    262 }  // namespace cc
    263