OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/output/overlay_renderer.h" |
| 6 |
| 7 #include <utility> |
| 8 #include <vector> |
| 9 |
| 10 #include "base/containers/hash_tables.h" |
| 11 #include "base/containers/scoped_ptr_hash_map.h" |
| 12 #include "base/debug/trace_event.h" |
| 13 #include "base/metrics/histogram.h" |
| 14 #include "cc/base/math_util.h" |
| 15 #include "cc/output/copy_output_request.h" |
| 16 #include "cc/quads/draw_quad.h" |
| 17 #include "ui/gfx/rect_conversions.h" |
| 18 #include "ui/gfx/transform.h" |
| 19 #include "ui/gfx/ozone/overlay_hal_ozone.h" |
| 20 |
| 21 namespace cc { |
| 22 |
| 23 namespace { |
| 24 |
| 25 class SingleOverlayOnTop : public OverlayRenderer::Strategy { |
| 26 public: |
| 27 SingleOverlayOnTop(gfx::OverlayHALOzone* hal); |
| 28 virtual bool Attempt(RenderPassList* render_passes_in_draw_order) OVERRIDE; |
| 29 private: |
| 30 gfx::OverlayHALOzone* hal_; |
| 31 }; |
| 32 |
| 33 SingleOverlayOnTop::SingleOverlayOnTop(gfx::OverlayHALOzone* hal) : hal_(hal) {} |
| 34 |
| 35 bool SingleOverlayOnTop::Attempt(RenderPassList* render_passes_in_draw_order) { |
| 36 // Only attempt to handle very simple case for now. |
| 37 if (render_passes_in_draw_order->size() != 1 || !hal_) |
| 38 return false; |
| 39 |
| 40 RenderPass* root_render_pass = render_passes_in_draw_order->back(); |
| 41 DCHECK(root_render_pass); |
| 42 |
| 43 QuadList& quad_list = root_render_pass->quad_list; |
| 44 QuadList::BackToFrontIterator candidate_quad = quad_list.BackToFrontEnd(); |
| 45 for (QuadList::BackToFrontIterator it = quad_list.BackToFrontBegin(); |
| 46 it != quad_list.BackToFrontEnd(); |
| 47 ++it) { |
| 48 const DrawQuad& quad = *(*it); |
| 49 if (//quad.material == DrawQuad::STREAM_VIDEO_CONTENT || |
| 50 //quad.material == DrawQuad::YUV_VIDEO_CONTENT || |
| 51 quad.material == DrawQuad::TEXTURE_CONTENT) { |
| 52 // Don't try for multiple surfaces. |
| 53 if (candidate_quad != quad_list.BackToFrontEnd()) |
| 54 return false; |
| 55 |
| 56 candidate_quad = it; |
| 57 break; |
| 58 } |
| 59 } |
| 60 |
| 61 // Found nothing useful. |
| 62 if (candidate_quad == quad_list.BackToFrontEnd()) |
| 63 return false; |
| 64 |
| 65 gfx::OverlayHALOzone::SurfaceCandidateList candidates; |
| 66 gfx::OverlayHALOzone::SurfaceCandidate candidate; |
| 67 const DrawQuad& quad = *(*candidate_quad); |
| 68 gfx::RectF float_rect(quad.rect); |
| 69 quad.quadTransform().TransformRect(&float_rect); |
| 70 candidate.rect = gfx::ToNearestRect(float_rect); |
| 71 candidate.format = gfx::OverlayHALOzone::RGBA; |
| 72 candidates.push_back(candidate); |
| 73 |
| 74 if (quad_list.size() != 1) { |
| 75 gfx::OverlayHALOzone::SurfaceCandidate main_image; |
| 76 main_image.rect = root_render_pass->output_rect; |
| 77 main_image.format = gfx::OverlayHALOzone::RGBA; |
| 78 candidates.push_back(main_image); |
| 79 } |
| 80 |
| 81 // Ask for support |
| 82 hal_->CheckOverlaySupport(&candidates); |
| 83 |
| 84 // Only one quad in the main pass, just overlay. |
| 85 if (candidates.size() == 1 && candidates[0].overlay_handled) { |
| 86 root_render_pass->handled_by_overlay_hardware = true; |
| 87 root_render_pass->should_render = false; |
| 88 } else if (candidates.size() == 2 && candidates[0].overlay_handled) { |
| 89 // Add a pass for an overlayable quad |
| 90 scoped_ptr<RenderPass> overlay_pass = RenderPass::Create(); |
| 91 overlay_pass->handled_by_overlay_hardware = true; |
| 92 overlay_pass->overlay_hardware_rect = candidate.rect; |
| 93 overlay_pass->should_render = false; |
| 94 |
| 95 scoped_ptr<DrawQuad> overlay_quad = |
| 96 quad_list.take((candidate_quad + 1).base()); |
| 97 quad_list.erase((candidate_quad + 1).base()); |
| 98 overlay_pass->quad_list.push_back(overlay_quad.PassAs<DrawQuad>()); |
| 99 render_passes_in_draw_order->insert(render_passes_in_draw_order->begin(), |
| 100 overlay_pass.PassAs<RenderPass>()); |
| 101 } |
| 102 return true; |
| 103 } |
| 104 |
| 105 } |
| 106 |
| 107 OverlayRenderer::OverlayRenderer() {} |
| 108 OverlayRenderer::~OverlayRenderer() {} |
| 109 |
| 110 void OverlayRenderer::Initialize() { |
| 111 gfx::OverlayHALOzone* hal = gfx::OverlayHALOzone::GetInstance(); |
| 112 if (!hal) |
| 113 return; |
| 114 |
| 115 strategies_.push_back(scoped_ptr<Strategy>(new SingleOverlayOnTop(hal))); |
| 116 } |
| 117 |
| 118 void OverlayRenderer::ProcessForOverlays( |
| 119 RenderPassList* render_passes_in_draw_order) { |
| 120 for (size_t i = 0; i < strategies_.size(); i ++) { |
| 121 if (strategies_[i]->Attempt(render_passes_in_draw_order)) |
| 122 return; |
| 123 } |
| 124 } |
| 125 |
| 126 } // namespace cc |
OLD | NEW |