summaryrefslogtreecommitdiff
path: root/chromium/cc/output/output_surface.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/output/output_surface.cc')
-rw-r--r--chromium/cc/output/output_surface.cc267
1 files changed, 111 insertions, 156 deletions
diff --git a/chromium/cc/output/output_surface.cc b/chromium/cc/output/output_surface.cc
index be990cc0cb7..555fea27911 100644
--- a/chromium/cc/output/output_surface.cc
+++ b/chromium/cc/output/output_surface.cc
@@ -4,6 +4,7 @@
#include "cc/output/output_surface.h"
+#include <algorithm>
#include <set>
#include <string>
#include <vector>
@@ -15,11 +16,11 @@
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "cc/output/compositor_frame.h"
+#include "cc/output/compositor_frame_ack.h"
#include "cc/output/managed_memory_policy.h"
#include "cc/output/output_surface_client.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
-#include "third_party/WebKit/public/platform/WebGraphicsMemoryAllocation.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/rect.h"
@@ -30,67 +31,9 @@ using std::string;
using std::vector;
namespace cc {
-namespace {
-
-ManagedMemoryPolicy::PriorityCutoff ConvertPriorityCutoff(
- WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff) {
- // This is simple a 1:1 map, the names differ only because the WebKit names
- // should be to match the cc names.
- switch (priority_cutoff) {
- case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing:
- return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
- case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly:
- return ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY;
- case WebKit::WebGraphicsMemoryAllocation::
- PriorityCutoffAllowVisibleAndNearby:
- return ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE;
- case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything:
- return ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING;
- }
- NOTREACHED();
- return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
-}
-
-} // anonymous namespace
-
-class OutputSurfaceCallbacks
- : public WebKit::WebGraphicsContext3D::
- WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
- public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback,
- public WebKit::WebGraphicsContext3D::
- WebGraphicsMemoryAllocationChangedCallbackCHROMIUM {
- public:
- explicit OutputSurfaceCallbacks(OutputSurface* client)
- : client_(client) {
- DCHECK(client_);
- }
-
- // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation.
- virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(NULL); }
-
- // WK:WGC3D::WGContextLostCallback implementation.
- virtual void onContextLost() { client_->DidLoseOutputSurface(); }
-
- // WK:WGC3D::WGMemoryAllocationChangedCallbackCHROMIUM implementation.
- virtual void onMemoryAllocationChanged(
- WebKit::WebGraphicsMemoryAllocation allocation) {
- ManagedMemoryPolicy policy(
- allocation.bytesLimitWhenVisible,
- ConvertPriorityCutoff(allocation.priorityCutoffWhenVisible),
- allocation.bytesLimitWhenNotVisible,
- ConvertPriorityCutoff(allocation.priorityCutoffWhenNotVisible),
- ManagedMemoryPolicy::kDefaultNumResourcesLimit);
- bool discard_backbuffer = !allocation.suggestHaveBackbuffer;
- client_->SetMemoryPolicy(policy, discard_backbuffer);
- }
-
- private:
- OutputSurface* client_;
-};
-OutputSurface::OutputSurface(
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
- : context3d_(context3d.Pass()),
+OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider)
+ : context_provider_(context_provider),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
@@ -98,10 +41,10 @@ OutputSurface::OutputSurface(
max_frames_pending_(0),
pending_swap_buffers_(0),
needs_begin_frame_(false),
- begin_frame_pending_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false) {
-}
+ check_for_retroactive_begin_frame_pending_(false),
+ external_stencil_test_enabled_(false) {}
OutputSurface::OutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device)
@@ -113,15 +56,15 @@ OutputSurface::OutputSurface(
max_frames_pending_(0),
pending_swap_buffers_(0),
needs_begin_frame_(false),
- begin_frame_pending_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false) {
-}
+ check_for_retroactive_begin_frame_pending_(false),
+ external_stencil_test_enabled_(false) {}
OutputSurface::OutputSurface(
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
+ scoped_refptr<ContextProvider> context_provider,
scoped_ptr<cc::SoftwareOutputDevice> software_device)
- : context3d_(context3d.Pass()),
+ : context_provider_(context_provider),
software_device_(software_device.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
@@ -130,10 +73,10 @@ OutputSurface::OutputSurface(
max_frames_pending_(0),
pending_swap_buffers_(0),
needs_begin_frame_(false),
- begin_frame_pending_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false) {
-}
+ check_for_retroactive_begin_frame_pending_(false),
+ external_stencil_test_enabled_(false) {}
void OutputSurface::InitializeBeginFrameEmulation(
base::SingleThreadTaskRunner* task_runner,
@@ -192,7 +135,7 @@ void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
void OutputSurface::SetNeedsBeginFrame(bool enable) {
TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
needs_begin_frame_ = enable;
- begin_frame_pending_ = false;
+ client_ready_for_begin_frame_ = true;
if (frame_rate_controller_) {
BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
if (skipped.IsValid())
@@ -204,14 +147,14 @@ void OutputSurface::SetNeedsBeginFrame(bool enable) {
void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
TRACE_EVENT2("cc", "OutputSurface::BeginFrame",
- "begin_frame_pending_", begin_frame_pending_,
+ "client_ready_for_begin_frame_", client_ready_for_begin_frame_,
"pending_swap_buffers_", pending_swap_buffers_);
- if (!needs_begin_frame_ || begin_frame_pending_ ||
+ if (!needs_begin_frame_ || !client_ready_for_begin_frame_ ||
(pending_swap_buffers_ >= max_frames_pending_ &&
max_frames_pending_ > 0)) {
skipped_begin_frame_args_ = args;
} else {
- begin_frame_pending_ = true;
+ client_ready_for_begin_frame_ = false;
client_->BeginFrame(args);
// args might be an alias for skipped_begin_frame_args_.
// Do not reset it before calling BeginFrame!
@@ -219,8 +162,13 @@ void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
}
}
-base::TimeDelta OutputSurface::RetroactiveBeginFramePeriod() {
- return BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
+base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
+ // TODO(brianderson): Remove the alternative deadline once we have better
+ // deadline estimations.
+ base::TimeTicks alternative_deadline =
+ skipped_begin_frame_args_.frame_time +
+ BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
+ return std::max(skipped_begin_frame_args_.deadline, alternative_deadline);
}
void OutputSurface::PostCheckForRetroactiveBeginFrame() {
@@ -238,18 +186,11 @@ void OutputSurface::PostCheckForRetroactiveBeginFrame() {
void OutputSurface::CheckForRetroactiveBeginFrame() {
TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
check_for_retroactive_begin_frame_pending_ = false;
- base::TimeTicks now = base::TimeTicks::Now();
- base::TimeTicks alternative_deadline =
- skipped_begin_frame_args_.frame_time +
- RetroactiveBeginFramePeriod();
- if (now < skipped_begin_frame_args_.deadline ||
- now < alternative_deadline) {
+ if (base::TimeTicks::Now() < RetroactiveBeginFrameDeadline())
BeginFrame(skipped_begin_frame_args_);
- }
}
void OutputSurface::DidSwapBuffers() {
- begin_frame_pending_ = false;
pending_swap_buffers_++;
TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers",
"pending_swap_buffers_", pending_swap_buffers_);
@@ -258,56 +199,63 @@ void OutputSurface::DidSwapBuffers() {
PostCheckForRetroactiveBeginFrame();
}
-void OutputSurface::OnSwapBuffersComplete(const CompositorFrameAck* ack) {
+void OutputSurface::OnSwapBuffersComplete() {
pending_swap_buffers_--;
TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete",
"pending_swap_buffers_", pending_swap_buffers_);
- client_->OnSwapBuffersComplete(ack);
+ client_->OnSwapBuffersComplete();
if (frame_rate_controller_)
frame_rate_controller_->DidSwapBuffersComplete();
PostCheckForRetroactiveBeginFrame();
}
+void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
+ client_->ReclaimResources(ack);
+}
+
void OutputSurface::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
- begin_frame_pending_ = false;
+ client_ready_for_begin_frame_ = true;
pending_swap_buffers_ = 0;
+ skipped_begin_frame_args_ = BeginFrameArgs();
+ if (frame_rate_controller_)
+ frame_rate_controller_->SetActive(false);
client_->DidLoseOutputSurface();
}
void OutputSurface::SetExternalStencilTest(bool enabled) {
- client_->SetExternalStencilTest(enabled);
+ external_stencil_test_enabled_ = enabled;
}
void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) {
- client_->SetExternalDrawConstraints(transform, viewport);
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) {
+ client_->SetExternalDrawConstraints(
+ transform, viewport, clip, valid_for_tile_management);
}
OutputSurface::~OutputSurface() {
if (frame_rate_controller_)
frame_rate_controller_->SetActive(false);
-
- if (context3d_) {
- context3d_->setSwapBuffersCompleteCallbackCHROMIUM(NULL);
- context3d_->setContextLostCallback(NULL);
- context3d_->setMemoryAllocationChangedCallbackCHROMIUM(NULL);
- }
+ ResetContext3d();
}
-bool OutputSurface::ForcedDrawToSoftwareDevice() const {
- return false;
+bool OutputSurface::HasExternalStencilTest() const {
+ return external_stencil_test_enabled_;
}
+bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; }
+
bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
DCHECK(client);
client_ = client;
bool success = true;
- if (context3d_) {
- success = context3d_->makeContextCurrent();
+ if (context_provider_) {
+ success = context_provider_->BindToCurrentThread();
if (success)
- SetContext3D(context3d_.Pass());
+ SetUpContext3d();
}
if (!success)
@@ -316,71 +264,78 @@ bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
return success;
}
-bool OutputSurface::InitializeAndSetContext3D(
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
+bool OutputSurface::InitializeAndSetContext3d(
+ scoped_refptr<ContextProvider> context_provider,
scoped_refptr<ContextProvider> offscreen_context_provider) {
- DCHECK(!context3d_);
- DCHECK(context3d);
+ DCHECK(!context_provider_);
+ DCHECK(context_provider);
DCHECK(client_);
bool success = false;
- if (context3d->makeContextCurrent()) {
- SetContext3D(context3d.Pass());
+ if (context_provider->BindToCurrentThread()) {
+ context_provider_ = context_provider;
+ SetUpContext3d();
if (client_->DeferredInitialize(offscreen_context_provider))
success = true;
}
if (!success)
- ResetContext3D();
+ ResetContext3d();
return success;
}
void OutputSurface::ReleaseGL() {
DCHECK(client_);
- DCHECK(context3d_);
+ DCHECK(context_provider_);
client_->ReleaseGL();
- ResetContext3D();
+ ResetContext3d();
}
-void OutputSurface::SetContext3D(
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d) {
- DCHECK(!context3d_);
- DCHECK(context3d);
+void OutputSurface::SetUpContext3d() {
+ DCHECK(context_provider_);
DCHECK(client_);
- string extensions_string = UTF16ToASCII(context3d->getString(GL_EXTENSIONS));
- vector<string> extensions_list;
- base::SplitString(extensions_string, ' ', &extensions_list);
- set<string> extensions(extensions_list.begin(), extensions_list.end());
- has_gl_discard_backbuffer_ =
- extensions.count("GL_CHROMIUM_discard_backbuffer") > 0;
- has_swap_buffers_complete_callback_ =
- extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0;
-
-
- context3d_ = context3d.Pass();
- callbacks_.reset(new OutputSurfaceCallbacks(this));
- context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
- context3d_->setContextLostCallback(callbacks_.get());
- context3d_->setMemoryAllocationChangedCallbackCHROMIUM(callbacks_.get());
-}
-
-void OutputSurface::ResetContext3D() {
- context3d_.reset();
- callbacks_.reset();
+ const ContextProvider::Capabilities& caps =
+ context_provider_->ContextCapabilities();
+
+ has_gl_discard_backbuffer_ = caps.discard_backbuffer;
+ has_swap_buffers_complete_callback_ = caps.swapbuffers_complete_callback;
+
+ context_provider_->SetLostContextCallback(
+ base::Bind(&OutputSurface::DidLoseOutputSurface,
+ base::Unretained(this)));
+ context_provider_->SetSwapBuffersCompleteCallback(base::Bind(
+ &OutputSurface::OnSwapBuffersComplete, base::Unretained(this)));
+ context_provider_->SetMemoryPolicyChangedCallback(
+ base::Bind(&OutputSurface::SetMemoryPolicy,
+ base::Unretained(this)));
+}
+
+void OutputSurface::ResetContext3d() {
+ if (context_provider_.get()) {
+ context_provider_->SetLostContextCallback(
+ ContextProvider::LostContextCallback());
+ context_provider_->SetSwapBuffersCompleteCallback(
+ ContextProvider::SwapBuffersCompleteCallback());
+ context_provider_->SetMemoryPolicyChangedCallback(
+ ContextProvider::MemoryPolicyChangedCallback());
+ }
+ context_provider_ = NULL;
}
void OutputSurface::EnsureBackbuffer() {
- DCHECK(context3d_);
- if (has_gl_discard_backbuffer_)
- context3d_->ensureBackbufferCHROMIUM();
+ if (context_provider_ && has_gl_discard_backbuffer_)
+ context_provider_->Context3d()->ensureBackbufferCHROMIUM();
+ if (software_device_)
+ software_device_->EnsureBackbuffer();
}
void OutputSurface::DiscardBackbuffer() {
- DCHECK(context3d_);
- if (has_gl_discard_backbuffer_)
- context3d_->discardBackbufferCHROMIUM();
+ if (context_provider_ && has_gl_discard_backbuffer_)
+ context_provider_->Context3d()->discardBackbufferCHROMIUM();
+ if (software_device_)
+ software_device_->DiscardBackbuffer();
}
void OutputSurface::Reshape(gfx::Size size, float scale_factor) {
@@ -389,8 +344,8 @@ void OutputSurface::Reshape(gfx::Size size, float scale_factor) {
surface_size_ = size;
device_scale_factor_ = scale_factor;
- if (context3d_) {
- context3d_->reshapeWithScaleFactor(
+ if (context_provider_) {
+ context_provider_->Context3d()->reshapeWithScaleFactor(
size.width(), size.height(), scale_factor);
}
if (software_device_)
@@ -402,8 +357,8 @@ gfx::Size OutputSurface::SurfaceSize() const {
}
void OutputSurface::BindFramebuffer() {
- DCHECK(context3d_);
- context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0);
+ DCHECK(context_provider_);
+ context_provider_->Context3d()->bindFramebuffer(GL_FRAMEBUFFER, 0);
}
void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
@@ -413,20 +368,21 @@ void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
return;
}
- DCHECK(context3d_);
+ DCHECK(context_provider_);
DCHECK(frame->gl_frame_data);
if (frame->gl_frame_data->sub_buffer_rect ==
gfx::Rect(frame->gl_frame_data->size)) {
// Note that currently this has the same effect as SwapBuffers; we should
// consider exposing a different entry point on WebGraphicsContext3D.
- context3d()->prepareTexture();
+ context_provider_->Context3d()->prepareTexture();
} else {
gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect;
- context3d()->postSubBufferCHROMIUM(sub_buffer_rect.x(),
- sub_buffer_rect.y(),
- sub_buffer_rect.width(),
- sub_buffer_rect.height());
+ context_provider_->Context3d()->postSubBufferCHROMIUM(
+ sub_buffer_rect.x(),
+ sub_buffer_rect.y(),
+ sub_buffer_rect.width(),
+ sub_buffer_rect.height());
}
if (!has_swap_buffers_complete_callback_)
@@ -437,10 +393,9 @@ void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
void OutputSurface::PostSwapBuffersComplete() {
base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&OutputSurface::OnSwapBuffersComplete,
- weak_ptr_factory_.GetWeakPtr(),
- static_cast<CompositorFrameAck*>(NULL)));
+ FROM_HERE,
+ base::Bind(&OutputSurface::OnSwapBuffersComplete,
+ weak_ptr_factory_.GetWeakPtr()));
}
void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy,