Skip to content

Commit

Permalink
Start of hardware overlay support in CC with Ubercompositor.
Browse files Browse the repository at this point in the history
I'm trying to introduce everything as small unit tested pieces.

This adds some machinery for checking if quads inside a render pass could
be placed into an overlay. A capability checker is added to the output
surface, so that a particular overlay configuration could be validated
against a specific display device. If an external monitor is plugged in,
its output surface may behave differently that that of the primary on
a laptop, for example.

The intention is for OverlayCandidates checker to be created as part of
BrowserCompositorOutputSurface where the actual hardware knowledge can
be delegated to the Ozone platform and the HW specific bits can live there,
leaving CC and content platform agnostic.

BUG=

Review URL: https://codereview.chromium.org/197223003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258209 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
alexst@chromium.org committed Mar 20, 2014
1 parent 47be222 commit 63880f8
Show file tree
Hide file tree
Showing 21 changed files with 811 additions and 19 deletions.
7 changes: 7 additions & 0 deletions cc/cc.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@
'output/output_surface.cc',
'output/output_surface.h',
'output/output_surface_client.h',
'output/overlay_candidate.cc',
'output/overlay_candidate.h',
'output/overlay_candidate_validator.h',
'output/overlay_processor.cc',
'output/overlay_processor.h',
'output/overlay_strategy_single_on_top.cc',
'output/overlay_strategy_single_on_top.h',
'output/program_binding.cc',
'output/program_binding.h',
'output/render_surface_filters.cc',
Expand Down
1 change: 1 addition & 0 deletions cc/cc_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
'output/filter_operations_unittest.cc',
'output/gl_renderer_unittest.cc',
'output/output_surface_unittest.cc',
'output/overlay_unittest.cc',
'output/renderer_pixeltest.cc',
'output/shader_unittest.cc',
'output/software_renderer_unittest.cc',
Expand Down
7 changes: 7 additions & 0 deletions cc/output/output_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "cc/base/cc_export.h"
#include "cc/base/rolling_time_delta_history.h"
#include "cc/output/context_provider.h"
#include "cc/output/overlay_candidate_validator.h"
#include "cc/output/software_output_device.h"
#include "cc/scheduler/frame_rate_controller.h"

Expand Down Expand Up @@ -139,6 +140,11 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// device is present, returns 0.
base::TimeDelta GpuLatencyEstimate();

// Get the class capable of informing cc of hardware overlay capability.
OverlayCandidateValidator* overlay_candidate_validator() const {
return overlay_candidate_validator_.get();
}

protected:
// Synchronously initialize context3d and enter hardware mode.
// This can only supported in threaded compositing mode.
Expand All @@ -154,6 +160,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
struct OutputSurface::Capabilities capabilities_;
scoped_refptr<ContextProvider> context_provider_;
scoped_ptr<SoftwareOutputDevice> software_device_;
scoped_ptr<OverlayCandidateValidator> overlay_candidate_validator_;
gfx::Size surface_size_;
float device_scale_factor_;

Expand Down
17 changes: 17 additions & 0 deletions cc/output/overlay_candidate.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2014 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_candidate_validator.h"

namespace cc {

OverlayCandidate::OverlayCandidate()
: transform(NONE),
format(RGBA_8888),
uv_rect(0.f, 0.f, 1.f, 1.f),
overlay_handled(false) {}

OverlayCandidate::~OverlayCandidate() {}

} // namespace cc
46 changes: 46 additions & 0 deletions cc/output/overlay_candidate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2014 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.

#ifndef CC_OUTPUT_OVERLAY_CANDIDATE_H_
#define CC_OUTPUT_OVERLAY_CANDIDATE_H_

#include <vector>

#include "base/basictypes.h"
#include "cc/base/cc_export.h"
#include "cc/resources/resource_format.h"
#include "ui/gfx/geometry/rect.h"

namespace cc {

struct CC_EXPORT OverlayCandidate {
enum OverlayTransform {
NONE,
FLIP_HORIZONTAL,
FLIP_VERTICAL,
ROTATE_90,
ROTATE_180,
ROTATE_270,
};

OverlayCandidate();
~OverlayCandidate();

// Transformation to apply to layer during composition.
OverlayTransform transform;
// Format of the buffer to composite.
ResourceFormat format;
// Rect on the display to position the overlay to.
gfx::Rect display_rect;
// Crop within the buffer to be placed inside |display_rect|.
gfx::RectF uv_rect;

// To be modified by the implementer if this candidate can go into
// an overlay.
bool overlay_handled;
};

} // namespace cc

#endif // CC_OUTPUT_OVERLAY_CANDIDATE_H_
35 changes: 35 additions & 0 deletions cc/output/overlay_candidate_validator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2014 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.

#ifndef CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_
#define CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_

#include <vector>

#include "base/basictypes.h"
#include "cc/base/cc_export.h"
#include "cc/output/overlay_candidate.h"
#include "cc/resources/resource_format.h"
#include "ui/gfx/geometry/rect.h"

namespace cc {

// This class that can be used to answer questions about possible overlay
// configurations for a particular output device.
class CC_EXPORT OverlayCandidateValidator {
public:
typedef std::vector<OverlayCandidate> OverlayCandidateList;

// A list of possible overlay candidates is presented to this function.
// The expected result is that those candidates that can be in a separate
// plane are marked with |overlay_handled| set to true, otherwise they are
// to be traditionally composited.
virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) = 0;

virtual ~OverlayCandidateValidator() {}
};

} // namespace cc

#endif // CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_
42 changes: 42 additions & 0 deletions cc/output/overlay_processor.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2014 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_processor.h"

#include "cc/output/output_surface.h"
#include "cc/output/overlay_strategy_single_on_top.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/transform.h"

namespace cc {

OverlayProcessor::OverlayProcessor(OutputSurface* surface,
ResourceProvider* resource_provider)
: surface_(surface), resource_provider_(resource_provider) {}

void OverlayProcessor::Initialize() {
DCHECK(surface_);
DCHECK(resource_provider_);
OverlayCandidateValidator* candidates =
surface_->overlay_candidate_validator();
if (candidates) {
strategies_.push_back(scoped_ptr<Strategy>(
new OverlayStrategySingleOnTop(candidates, resource_provider_)));
}
}

OverlayProcessor::~OverlayProcessor() {}

void OverlayProcessor::ProcessForOverlays(
RenderPassList* render_passes_in_draw_order) {
for (StrategyList::iterator it = strategies_.begin(); it != strategies_.end();
++it) {
if ((*it)->Attempt(render_passes_in_draw_order))
return;
}
}

} // namespace cc
48 changes: 48 additions & 0 deletions cc/output/overlay_processor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2014 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.

#ifndef CC_OUTPUT_OVERLAY_PROCESSOR_H_
#define CC_OUTPUT_OVERLAY_PROCESSOR_H_

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/quads/render_pass.h"

namespace cc {
class OutputSurface;
class ResourceProvider;

class CC_EXPORT OverlayProcessor {
public:
class CC_EXPORT Strategy {
public:
virtual ~Strategy() {}
// Returns false if the strategy cannot be made to work with the
// current set of render passes. Returns true if the strategy was successful
// and adds any additional passes necessary to represent overlays to
// |render_passes_in_draw_order|.
virtual bool Attempt(RenderPassList* render_passes_in_draw_order) = 0;
};
typedef ScopedPtrVector<Strategy> StrategyList;

OverlayProcessor(OutputSurface* surface, ResourceProvider* resource_provider);
virtual ~OverlayProcessor();
// Virtual to allow testing different strategies.
virtual void Initialize();

void ProcessForOverlays(RenderPassList* render_passes_in_draw_order);

protected:
StrategyList strategies_;
OutputSurface* surface_;
ResourceProvider* resource_provider_;

private:
DISALLOW_COPY_AND_ASSIGN(OverlayProcessor);
};

} // namespace cc

#endif // CC_OUTPUT_OVERLAY_PROCESSOR_H_
81 changes: 81 additions & 0 deletions cc/output/overlay_strategy_single_on_top.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2014 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_strategy_single_on_top.h"

#include "cc/output/output_surface.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/transform.h"

namespace cc {

OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
OverlayCandidateValidator* capability_checker,
ResourceProvider* resource_provider)
: capability_checker_(capability_checker),
resource_provider_(resource_provider) {}

bool OverlayStrategySingleOnTop::Attempt(
RenderPassList* render_passes_in_draw_order) {
// Only attempt to handle very simple case for now.
if (!capability_checker_)
return false;

RenderPass* root_render_pass = render_passes_in_draw_order->back();
DCHECK(root_render_pass);

QuadList& quad_list = root_render_pass->quad_list;
const DrawQuad* candidate_quad = quad_list.front();
if (candidate_quad->material != DrawQuad::TEXTURE_CONTENT)
return false;

const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(candidate_quad);
if (!resource_provider_->AllowOverlay(quad.resource_id))
return false;

// Simple quads only.
if (!quad.quadTransform().IsIdentityOrTranslation() || quad.needs_blending ||
quad.shared_quad_state->opacity != 1.f ||
quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode ||
quad.premultiplied_alpha || quad.background_color != SK_ColorTRANSPARENT)
return false;

// Add our primary surface.
OverlayCandidateValidator::OverlayCandidateList candidates;
OverlayCandidate main_image;
main_image.display_rect = root_render_pass->output_rect;
main_image.format = RGBA_8888;
candidates.push_back(main_image);

// Add the overlay.
OverlayCandidate candidate;
gfx::RectF float_rect(quad.rect);
quad.quadTransform().TransformRect(&float_rect);
candidate.transform =
quad.flipped ? OverlayCandidate::FLIP_VERTICAL : OverlayCandidate::NONE;
candidate.display_rect = gfx::ToNearestRect(float_rect);
candidate.uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
candidate.format = RGBA_8888;
candidates.push_back(candidate);

// Check for support.
capability_checker_->CheckOverlaySupport(&candidates);

// If the candidate can be handled by an overlay, create a pass for it.
if (candidates[1].overlay_handled) {
scoped_ptr<RenderPass> overlay_pass = RenderPass::Create();
overlay_pass->overlay_state = RenderPass::SIMPLE_OVERLAY;

scoped_ptr<DrawQuad> overlay_quad = quad_list.take(quad_list.begin());
quad_list.erase(quad_list.begin());
overlay_pass->quad_list.push_back(overlay_quad.Pass());
render_passes_in_draw_order->insert(render_passes_in_draw_order->begin(),
overlay_pass.Pass());
}
return candidates[1].overlay_handled;
}

} // namespace cc
31 changes: 31 additions & 0 deletions cc/output/overlay_strategy_single_on_top.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2014 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.

#ifndef CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_
#define CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/output/overlay_processor.h"
#include "cc/quads/render_pass.h"

namespace cc {
class OverlayCandidateValidator;

class CC_EXPORT OverlayStrategySingleOnTop : public OverlayProcessor::Strategy {
public:
OverlayStrategySingleOnTop(OverlayCandidateValidator* capability_checker,
ResourceProvider* resource_provider);
virtual bool Attempt(RenderPassList* render_passes_in_draw_order) OVERRIDE;

private:
OverlayCandidateValidator* capability_checker_;
ResourceProvider* resource_provider_;
DISALLOW_COPY_AND_ASSIGN(OverlayStrategySingleOnTop);
};

} // namespace cc

#endif // CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_
Loading

0 comments on commit 63880f8

Please sign in to comment.