Commit d438d276 authored by achaulk's avatar achaulk Committed by Commit bot

Surfaceless OutputSurface implementation.

Implements an OutputSurface that uses render-to-texture and overlays
to display the main surface. Buffering of frames is implemented
internally as there is no system-provided surface.

BUG=380861

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

Cr-Commit-Position: refs/heads/master@{#295119}
parent f8fb5865
......@@ -34,6 +34,12 @@ void TestGLES2Interface::GenFramebuffers(GLsizei n, GLuint* framebuffers) {
}
}
void TestGLES2Interface::GenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
for (GLsizei i = 0; i < n; ++i) {
renderbuffers[i] = test_context_->createRenderbuffer();
}
}
void TestGLES2Interface::GenQueriesEXT(GLsizei n, GLuint* queries) {
for (GLsizei i = 0; i < n; ++i) {
queries[i] = test_context_->createQueryEXT();
......@@ -160,6 +166,10 @@ void TestGLES2Interface::Enable(GLenum cap) { test_context_->enable(cap); }
void TestGLES2Interface::Disable(GLenum cap) { test_context_->disable(cap); }
void TestGLES2Interface::BindRenderbuffer(GLenum target, GLuint buffer) {
test_context_->bindRenderbuffer(target, buffer);
}
void TestGLES2Interface::BindFramebuffer(GLenum target, GLuint buffer) {
test_context_->bindFramebuffer(target, buffer);
}
......@@ -224,6 +234,29 @@ void TestGLES2Interface::TexParameteri(GLenum target,
test_context_->texParameteri(target, pname, param);
}
void TestGLES2Interface::FramebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer) {
test_context_->framebufferRenderbuffer(
target, attachment, renderbuffertarget, renderbuffer);
}
void TestGLES2Interface::FramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level) {
test_context_->framebufferTexture2D(
target, attachment, textarget, texture, level);
}
void TestGLES2Interface::RenderbufferStorage(GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height) {
test_context_->renderbufferStorage(target, internalformat, width, height);
}
void TestGLES2Interface::AsyncTexImage2DCHROMIUM(GLenum target,
GLint level,
GLenum internalformat,
......
......@@ -18,6 +18,7 @@ class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
virtual void GenTextures(GLsizei n, GLuint* textures) OVERRIDE;
virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE;
virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) OVERRIDE;
virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) OVERRIDE;
virtual void GenQueriesEXT(GLsizei n, GLuint* queries) OVERRIDE;
virtual void DeleteTextures(GLsizei n, const GLuint* textures) OVERRIDE;
......@@ -65,6 +66,7 @@ class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
virtual void Disable(GLenum cap) OVERRIDE;
virtual void BindBuffer(GLenum target, GLuint buffer) OVERRIDE;
virtual void BindRenderbuffer(GLenum target, GLuint buffer) OVERRIDE;
virtual void BindFramebuffer(GLenum target, GLuint buffer) OVERRIDE;
virtual void TexImage2D(GLenum target,
......@@ -137,6 +139,19 @@ class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
virtual void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) OVERRIDE;
virtual void ReleaseTexImage2DCHROMIUM(GLenum target,
GLint image_id) OVERRIDE;
virtual void FramebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer) OVERRIDE;
virtual void FramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level) OVERRIDE;
virtual void RenderbufferStorage(GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height) OVERRIDE;
virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE;
virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
......
......@@ -73,6 +73,19 @@ class TestWebGraphicsContext3D {
const void* pixels) {}
virtual void waitAsyncTexImage2DCHROMIUM(GLenum target) {}
virtual void releaseTexImage2DCHROMIUM(GLenum target, GLint image_id) {}
virtual void framebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer) {}
virtual void framebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level) {}
virtual void renderbufferStorage(GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height) {}
virtual GLenum checkFramebufferStatus(GLenum target);
......
// 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 "content/browser/compositor/buffer_queue.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
namespace content {
BufferQueue::BufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
unsigned int internalformat)
: context_provider_(context_provider),
fbo_(0),
allocated_count_(0),
internalformat_(internalformat) {
}
BufferQueue::~BufferQueue() {
FreeAllSurfaces();
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
if (fbo_)
gl->DeleteFramebuffers(1, &fbo_);
}
bool BufferQueue::Initialize() {
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->GenFramebuffers(1, &fbo_);
return fbo_ != 0;
}
void BufferQueue::BindFramebuffer() {
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
if (!current_surface_.texture) {
current_surface_ = GetNextSurface();
gl->FramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
current_surface_.texture,
0);
}
}
void BufferQueue::SwapBuffers() {
in_flight_surfaces_.push(current_surface_);
current_surface_.texture = 0;
current_surface_.image = 0;
}
void BufferQueue::Reshape(const gfx::Size& size, float scale_factor) {
DCHECK(!current_surface_.texture);
if (size == size_)
return;
size_ = size;
// TODO: add stencil buffer when needed.
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
gl->FramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
FreeAllSurfaces();
}
void BufferQueue::PageFlipComplete() {
if (in_flight_surfaces_.size() > 1) {
available_surfaces_.push_back(in_flight_surfaces_.front());
in_flight_surfaces_.pop();
}
}
void BufferQueue::FreeAllSurfaces() {
FreeSurface(&current_surface_);
while (!in_flight_surfaces_.empty()) {
FreeSurface(&in_flight_surfaces_.front());
in_flight_surfaces_.pop();
}
for (size_t i = 0; i < available_surfaces_.size(); i++)
FreeSurface(&available_surfaces_[i]);
available_surfaces_.clear();
}
void BufferQueue::FreeSurface(AllocatedSurface* surface) {
if (surface->texture) {
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->BindTexture(GL_TEXTURE_2D, surface->texture);
gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, surface->image);
gl->DeleteTextures(1, &surface->texture);
gl->DestroyImageCHROMIUM(surface->image);
surface->image = 0;
surface->texture = 0;
allocated_count_--;
}
}
BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() {
if (!available_surfaces_.empty()) {
AllocatedSurface id = available_surfaces_.back();
available_surfaces_.pop_back();
return id;
}
unsigned int texture = 0;
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->GenTextures(1, &texture);
if (!texture)
return AllocatedSurface();
// We don't want to allow anything more than triple buffering.
DCHECK_LT(allocated_count_, 4U);
unsigned int id = context_provider_->ContextGL()->CreateImageCHROMIUM(
size_.width(),
size_.height(),
internalformat_,
GL_IMAGE_SCANOUT_CHROMIUM);
allocated_count_++;
gl->BindTexture(GL_TEXTURE_2D, texture);
gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, id);
return AllocatedSurface(texture, id);
}
} // namespace content
// 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 CONTENT_BROWSER_COMPOSITOR_BUFFERED_OUTPUT_SURFACE_H_
#define CONTENT_BROWSER_COMPOSITOR_BUFFERED_OUTPUT_SURFACE_H_
#include <queue>
#include <vector>
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "ui/gfx/size.h"
namespace cc {
class ContextProvider;
}
namespace content {
// Provides a surface that manages its own uffers, backed by
// CreateImageCHROMIUM. Double/triple buffering is implemented
// internally. Doublebuffering occurs if PageFlipComplete is called before
// the next BindFramebuffer call, otherwise it creates extra buffers.
class CONTENT_EXPORT BufferQueue {
public:
BufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
unsigned int internalformat);
~BufferQueue();
bool Initialize();
void BindFramebuffer();
void SwapBuffers();
void PageFlipComplete();
void Reshape(const gfx::Size& size, float scale_factor);
unsigned int current_texture_id() { return current_surface_.texture; }
private:
friend class BufferQueueTest;
struct AllocatedSurface {
AllocatedSurface() : texture(0), image(0) {}
AllocatedSurface(unsigned int texture, unsigned int image)
: texture(texture), image(image) {}
unsigned int texture;
unsigned int image;
};
void FreeAllSurfaces();
void FreeSurface(AllocatedSurface* surface);
// Return a surface, available to be drawn into.
AllocatedSurface GetNextSurface();
gfx::Size size_;
scoped_refptr<cc::ContextProvider> context_provider_;
unsigned int fbo_;
size_t allocated_count_;
unsigned int internalformat_;
AllocatedSurface current_surface_; // This surface is currently bound.
std::vector<AllocatedSurface> available_surfaces_; // These are free for use.
std::queue<AllocatedSurface> in_flight_surfaces_;
DISALLOW_COPY_AND_ASSIGN(BufferQueue);
};
} // namespace content
#endif // CONTENT_BROWSER_COMPOSITOR_BUFFERED_OUTPUT_SURFACE_H_
// 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 <set>
#include "cc/test/test_context_provider.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "content/browser/compositor/buffer_queue.h"
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2ext.h"
using ::testing::_;
using ::testing::Expectation;
using ::testing::Ne;
using ::testing::Return;
namespace content {
class BufferQueueTest : public ::testing::Test {
public:
virtual void SetUp() OVERRIDE {
scoped_refptr<cc::TestContextProvider> context_provider =
cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
context_provider->BindToCurrentThread();
output_surface_.reset(new BufferQueue(context_provider, GL_RGBA8_OES));
}
unsigned current_surface() { return output_surface_->current_surface_.image; }
const std::vector<BufferQueue::AllocatedSurface>& available_surfaces() {
return output_surface_->available_surfaces_;
}
const std::queue<BufferQueue::AllocatedSurface>& in_flight_surfaces() {
return output_surface_->in_flight_surfaces_;
}
int CountBuffers() {
int n = available_surfaces().size() + in_flight_surfaces().size();
if (current_surface())
n++;
return n;
}
// Check that each buffer is unique if present.
void CheckUnique() {
std::set<unsigned> buffers;
EXPECT_TRUE(InsertUnique(&buffers, current_surface()));
for (size_t i = 0; i < available_surfaces().size(); i++)
EXPECT_TRUE(InsertUnique(&buffers, available_surfaces()[i].image));
std::queue<BufferQueue::AllocatedSurface> copy = in_flight_surfaces();
while (!copy.empty()) {
EXPECT_TRUE(InsertUnique(&buffers, copy.front().image));
copy.pop();
}
}
protected:
bool InsertUnique(std::set<unsigned>* set, unsigned value) {
if (!value)
return true;
if (set->find(value) != set->end())
return false;
set->insert(value);
return true;
}
scoped_ptr<BufferQueue> output_surface_;
};
namespace {
class MockedContext : public cc::TestWebGraphicsContext3D {
public:
MOCK_METHOD2(bindFramebuffer, void(GLenum, GLuint));
MOCK_METHOD2(bindTexture, void(GLenum, GLuint));
MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
MOCK_METHOD4(createImageCHROMIUM, GLuint(GLsizei, GLsizei, GLenum, GLenum));
MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
MOCK_METHOD5(framebufferTexture2D,
void(GLenum, GLenum, GLenum, GLuint, GLint));
};
scoped_ptr<BufferQueue> CreateOutputSurfaceWithMock(MockedContext** context) {
*context = new MockedContext();
scoped_refptr<cc::TestContextProvider> context_provider =
cc::TestContextProvider::Create(
scoped_ptr<cc::TestWebGraphicsContext3D>(*context));
context_provider->BindToCurrentThread();
scoped_ptr<BufferQueue> buffer_queue(
new BufferQueue(context_provider, GL_RGBA8_OES));
buffer_queue->Initialize();
return buffer_queue.Pass();
}
TEST(BufferQueueStandaloneTest, FboInitialization) {
MockedContext* context;
scoped_ptr<BufferQueue> output_surface =
CreateOutputSurfaceWithMock(&context);
EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U)));
ON_CALL(*context, framebufferTexture2D(_, _, _, _, _))
.WillByDefault(Return());
output_surface->Reshape(gfx::Size(10, 20), 1.0f);
}
TEST(BufferQueueStandaloneTest, FboBinding) {
MockedContext* context;
scoped_ptr<BufferQueue> output_surface =
CreateOutputSurfaceWithMock(&context);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, Ne(0U)));
EXPECT_CALL(*context, destroyImageCHROMIUM(1));
Expectation image =
EXPECT_CALL(
*context,
createImageCHROMIUM(0, 0, GL_RGBA8_OES, GL_IMAGE_SCANOUT_CHROMIUM))
.WillOnce(Return(1));
Expectation fb =
EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U)));
Expectation tex = EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, Ne(0U)));
Expectation bind_tex =
EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1))
.After(tex, image);
EXPECT_CALL(
*context,
framebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Ne(0U), _))
.After(fb, bind_tex);
output_surface->BindFramebuffer();
}
TEST_F(BufferQueueTest, MultipleBindCalls) {
// Check that multiple bind calls do not create or change surfaces.
output_surface_->BindFramebuffer();
EXPECT_EQ(1, CountBuffers());
unsigned int fb = current_surface();
output_surface_->BindFramebuffer();
EXPECT_EQ(1, CountBuffers());
EXPECT_EQ(fb, current_surface());
}
TEST_F(BufferQueueTest, CheckDoubleBuffering) {
// Check buffer flow through double buffering path.
EXPECT_EQ(0, CountBuffers());
output_surface_->BindFramebuffer();
EXPECT_EQ(1, CountBuffers());
EXPECT_NE(0U, current_surface());
output_surface_->SwapBuffers();
EXPECT_EQ(1U, in_flight_surfaces().size());
output_surface_->PageFlipComplete();
EXPECT_EQ(1U, in_flight_surfaces().size());
output_surface_->BindFramebuffer();
EXPECT_EQ(2, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(1U, in_flight_surfaces().size());
output_surface_->SwapBuffers();
CheckUnique();
EXPECT_EQ(2U, in_flight_surfaces().size());
output_surface_->PageFlipComplete();
CheckUnique();
EXPECT_EQ(1U, in_flight_surfaces().size());
EXPECT_EQ(1U, available_surfaces().size());
output_surface_->BindFramebuffer();
EXPECT_EQ(2, CountBuffers());
CheckUnique();
EXPECT_TRUE(available_surfaces().empty());
}
TEST_F(BufferQueueTest, CheckTripleBuffering) {
// Check buffer flow through triple buffering path.
// This bit is the same sequence tested in the doublebuffering case.
output_surface_->BindFramebuffer();
output_surface_->SwapBuffers();
output_surface_->PageFlipComplete();
output_surface_->BindFramebuffer();
output_surface_->SwapBuffers();
EXPECT_EQ(2, CountBuffers());
CheckUnique();
EXPECT_EQ(2U, in_flight_surfaces().size());
output_surface_->BindFramebuffer();
EXPECT_EQ(3, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(2U, in_flight_surfaces().size());
output_surface_->PageFlipComplete();
EXPECT_EQ(3, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(1U, in_flight_surfaces().size());
EXPECT_EQ(1U, available_surfaces().size());
}
} // namespace
} // namespace content
......@@ -32,7 +32,7 @@ class GpuBrowserCompositorOutputSurface
virtual ~GpuBrowserCompositorOutputSurface();
private:
protected:
// cc::OutputSurface implementation.
virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
......
......@@ -18,6 +18,7 @@
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/browser_compositor_output_surface_proxy.h"
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
#include "content/browser/compositor/onscreen_display_client.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
......@@ -230,13 +231,26 @@ scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
return surface.PassAs<cc::OutputSurface>();
}
scoped_ptr<BrowserCompositorOutputSurface> surface(
new GpuBrowserCompositorOutputSurface(
context_provider,
per_compositor_data_[compositor]->surface_id,
&output_surface_map_,
compositor->vsync_manager(),
CreateOverlayCandidateValidator(compositor->widget())));
scoped_ptr<BrowserCompositorOutputSurface> surface;
#if defined(USE_OZONE)
if (ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
surface.reset(new GpuSurfacelessBrowserCompositorOutputSurface(
context_provider,
per_compositor_data_[compositor]->surface_id,
&output_surface_map_,
compositor->vsync_manager(),
CreateOverlayCandidateValidator(compositor->widget()),
GL_RGB8_OES));
}
#endif
if (!surface)
surface.reset(new GpuBrowserCompositorOutputSurface(
context_provider,
per_compositor_data_[compositor]->surface_id,
&output_surface_map_,
compositor->vsync_manager(),
CreateOverlayCandidateValidator(compositor->widget())));
if (data->reflector.get())
data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get());
......
// 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 "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
#include "cc/output/compositor_frame.h"
#include "content/browser/compositor/buffer_queue.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
namespace content {
GpuSurfacelessBrowserCompositorOutputSurface::
GpuSurfacelessBrowserCompositorOutputSurface(
const scoped_refptr<ContextProviderCommandBuffer>& context,
int surface_id,
IDMap<BrowserCompositorOutputSurface>* output_surface_map,
const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager,
scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator,
unsigned internalformat)
: GpuBrowserCompositorOutputSurface(context,
surface_id,
output_surface_map,
vsync_manager,
overlay_candidate_validator.Pass()),
internalformat_(internalformat) {
}
GpuSurfacelessBrowserCompositorOutputSurface::
~GpuSurfacelessBrowserCompositorOutputSurface() {
}
void GpuSurfacelessBrowserCompositorOutputSurface::SwapBuffers(
cc::CompositorFrame* frame) {
DCHECK(output_surface_);
const gfx::Size& size = frame->gl_frame_data->size;
context_provider_->ContextGL()->ScheduleOverlayPlaneCHROMIUM(
0,
GL_OVERLAY_TRANSFORM_NONE_CHROMIUM,
output_surface_->current_texture_id(),
0,
0,
size.width(),
size.height(),
0,
0,
1.0f,
1.0f);
output_surface_->SwapBuffers();
GpuBrowserCompositorOutputSurface::SwapBuffers(frame);
}
void GpuSurfacelessBrowserCompositorOutputSurface::OnSwapBuffersComplete() {
DCHECK(output_surface_);
output_surface_->PageFlipComplete();
GpuBrowserCompositorOutputSurface::OnSwapBuffersComplete();
}
void GpuSurfacelessBrowserCompositorOutputSurface::BindFramebuffer() {
DCHECK(output_surface_);
output_surface_->BindFramebuffer();
}
void GpuSurfacelessBrowserCompositorOutputSurface::Reshape(
const gfx::Size& size,
float scale_factor) {
GpuBrowserCompositorOutputSurface::Reshape(size, scale_factor);
DCHECK(output_surface_);
output_surface_->Reshape(SurfaceSize(), scale_factor);
}
bool GpuSurfacelessBrowserCompositorOutputSurface::BindToClient(
cc::OutputSurfaceClient* client) {
if (!GpuBrowserCompositorOutputSurface::BindToClient(client))
return false;
output_surface_.reset(new BufferQueue(context_provider_, internalformat_));
return output_surface_->Initialize();
}
} // namespace content
// 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 CONTENT_BROWSER_COMPOSITOR_GPU_SURFACELESS_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#define CONTENT_BROWSER_COMPOSITOR_GPU_SURFACELESS_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
namespace content {
class BufferQueue;
class GpuSurfacelessBrowserCompositorOutputSurface
: public GpuBrowserCompositorOutputSurface {
public:
GpuSurfacelessBrowserCompositorOutputSurface(
const scoped_refptr<ContextProviderCommandBuffer>& context,
int surface_id,
IDMap<BrowserCompositorOutputSurface>* output_surface_map,
const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager,
scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator,
unsigned internalformat);
virtual ~GpuSurfacelessBrowserCompositorOutputSurface();
private:
// cc::OutputSurface implementation.
virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
virtual void OnSwapBuffersComplete() OVERRIDE;
virtual void BindFramebuffer() OVERRIDE;
virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE;
virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE;
unsigned int internalformat_;
scoped_ptr<BufferQueue> output_surface_;
};
} // namespace content
#endif // CONTENT_BROWSER_COMPOSITOR_GPU_SURFACELESS_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
......@@ -1425,6 +1425,8 @@
'browser/compositor/browser_compositor_view_mac.h',
'browser/compositor/browser_compositor_view_private_mac.mm',
'browser/compositor/browser_compositor_view_private_mac.h',
'browser/compositor/buffer_queue.cc',
'browser/compositor/buffer_queue.h',
'browser/compositor/delegated_frame_host.cc',
'browser/compositor/delegated_frame_host.h',
'browser/compositor/gpu_process_transport_factory.cc',
......@@ -1447,6 +1449,8 @@
'browser/compositor/software_layer_mac.h',
'browser/compositor/gpu_browser_compositor_output_surface.cc',
'browser/compositor/gpu_browser_compositor_output_surface.h',
'browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc',
'browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h',
'browser/compositor/software_browser_compositor_output_surface.cc',
'browser/compositor/software_browser_compositor_output_surface.h',
'browser/compositor/software_output_device_mac.mm',
......
......@@ -405,6 +405,7 @@
'browser/byte_stream_unittest.cc',
'browser/child_process_security_policy_unittest.cc',
'browser/cocoa/system_hotkey_map_unittest.mm',
'browser/compositor/buffer_queue_unittest.cc',
'browser/compositor/software_browser_compositor_output_surface_unittest.cc',
'browser/compositor/software_output_device_ozone_unittest.cc',
'browser/databases_table_unittest.cc',
......
......@@ -122,6 +122,8 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
return SurfacelessEGL::Resize(size);
}
virtual bool SwapBuffers() OVERRIDE {
// TODO: this should be replaced by a fence when supported by the driver.
glFinish();
return ozone_surface_->OnSwapBuffers();
}
virtual bool ScheduleOverlayPlane(int z_order,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment