| Index: cc/output/overlay_renderer.cc
|
| diff --git a/cc/output/overlay_renderer.cc b/cc/output/overlay_renderer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..be9c8eb36cdecf9f2c78cdc60a760539b328decc
|
| --- /dev/null
|
| +++ b/cc/output/overlay_renderer.cc
|
| @@ -0,0 +1,126 @@
|
| +// Copyright 2012 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/output/overlay_renderer.h"
|
| +
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "base/containers/hash_tables.h"
|
| +#include "base/containers/scoped_ptr_hash_map.h"
|
| +#include "base/debug/trace_event.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "cc/base/math_util.h"
|
| +#include "cc/output/copy_output_request.h"
|
| +#include "cc/quads/draw_quad.h"
|
| +#include "ui/gfx/rect_conversions.h"
|
| +#include "ui/gfx/transform.h"
|
| +#include "ui/gfx/ozone/overlay_hal_ozone.h"
|
| +
|
| +namespace cc {
|
| +
|
| +namespace {
|
| +
|
| +class SingleOverlayOnTop : public OverlayRenderer::Strategy {
|
| + public:
|
| + SingleOverlayOnTop(gfx::OverlayHALOzone* hal);
|
| + virtual bool Attempt(RenderPassList* render_passes_in_draw_order) OVERRIDE;
|
| + private:
|
| + gfx::OverlayHALOzone* hal_;
|
| +};
|
| +
|
| +SingleOverlayOnTop::SingleOverlayOnTop(gfx::OverlayHALOzone* hal) : hal_(hal) {}
|
| +
|
| +bool SingleOverlayOnTop::Attempt(RenderPassList* render_passes_in_draw_order) {
|
| + // Only attempt to handle very simple case for now.
|
| + if (render_passes_in_draw_order->size() != 1 || !hal_)
|
| + return false;
|
| +
|
| + RenderPass* root_render_pass = render_passes_in_draw_order->back();
|
| + DCHECK(root_render_pass);
|
| +
|
| + QuadList& quad_list = root_render_pass->quad_list;
|
| + QuadList::BackToFrontIterator candidate_quad = quad_list.BackToFrontEnd();
|
| + for (QuadList::BackToFrontIterator it = quad_list.BackToFrontBegin();
|
| + it != quad_list.BackToFrontEnd();
|
| + ++it) {
|
| + const DrawQuad& quad = *(*it);
|
| + if (//quad.material == DrawQuad::STREAM_VIDEO_CONTENT ||
|
| + //quad.material == DrawQuad::YUV_VIDEO_CONTENT ||
|
| + quad.material == DrawQuad::TEXTURE_CONTENT) {
|
| + // Don't try for multiple surfaces.
|
| + if (candidate_quad != quad_list.BackToFrontEnd())
|
| + return false;
|
| +
|
| + candidate_quad = it;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // Found nothing useful.
|
| + if (candidate_quad == quad_list.BackToFrontEnd())
|
| + return false;
|
| +
|
| + gfx::OverlayHALOzone::SurfaceCandidateList candidates;
|
| + gfx::OverlayHALOzone::SurfaceCandidate candidate;
|
| + const DrawQuad& quad = *(*candidate_quad);
|
| + gfx::RectF float_rect(quad.rect);
|
| + quad.quadTransform().TransformRect(&float_rect);
|
| + candidate.rect = gfx::ToNearestRect(float_rect);
|
| + candidate.format = gfx::OverlayHALOzone::RGBA;
|
| + candidates.push_back(candidate);
|
| +
|
| + if (quad_list.size() != 1) {
|
| + gfx::OverlayHALOzone::SurfaceCandidate main_image;
|
| + main_image.rect = root_render_pass->output_rect;
|
| + main_image.format = gfx::OverlayHALOzone::RGBA;
|
| + candidates.push_back(main_image);
|
| + }
|
| +
|
| + // Ask for support
|
| + hal_->CheckOverlaySupport(&candidates);
|
| +
|
| + // Only one quad in the main pass, just overlay.
|
| + if (candidates.size() == 1 && candidates[0].overlay_handled) {
|
| + root_render_pass->handled_by_overlay_hardware = true;
|
| + root_render_pass->should_render = false;
|
| + } else if (candidates.size() == 2 && candidates[0].overlay_handled) {
|
| + // Add a pass for an overlayable quad
|
| + scoped_ptr<RenderPass> overlay_pass = RenderPass::Create();
|
| + overlay_pass->handled_by_overlay_hardware = true;
|
| + overlay_pass->overlay_hardware_rect = candidate.rect;
|
| + overlay_pass->should_render = false;
|
| +
|
| + scoped_ptr<DrawQuad> overlay_quad =
|
| + quad_list.take((candidate_quad + 1).base());
|
| + quad_list.erase((candidate_quad + 1).base());
|
| + overlay_pass->quad_list.push_back(overlay_quad.PassAs<DrawQuad>());
|
| + render_passes_in_draw_order->insert(render_passes_in_draw_order->begin(),
|
| + overlay_pass.PassAs<RenderPass>());
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +}
|
| +
|
| +OverlayRenderer::OverlayRenderer() {}
|
| +OverlayRenderer::~OverlayRenderer() {}
|
| +
|
| +void OverlayRenderer::Initialize() {
|
| + gfx::OverlayHALOzone* hal = gfx::OverlayHALOzone::GetInstance();
|
| + if (!hal)
|
| + return;
|
| +
|
| + strategies_.push_back(scoped_ptr<Strategy>(new SingleOverlayOnTop(hal)));
|
| +}
|
| +
|
| +void OverlayRenderer::ProcessForOverlays(
|
| + RenderPassList* render_passes_in_draw_order) {
|
| + for (size_t i = 0; i < strategies_.size(); i ++) {
|
| + if (strategies_[i]->Attempt(render_passes_in_draw_order))
|
| + return;
|
| + }
|
| +}
|
| +
|
| +} // namespace cc
|
|
|