Commit 055f8f2f authored by achaulk@chromium.org's avatar achaulk@chromium.org

ozone: gbm: Add overlay support

The surface builds up a list of overlays as they come in and HDC
is modified to do the page flip + present all overlays in one go.

BUG=380861
NOTRY=true

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282662 0039d316-1c4b-4281-b951-d872f2087c98
parent e7cd231b
......@@ -54,6 +54,9 @@ uint32_t DriSurface::GetHandle() const {
return backbuffer()->handle();
}
void DriSurface::PreSwapBuffers() {
}
// This call is made after the hardware just started displaying our back buffer.
// We need to update our pointer reference and synchronize the two buffers.
void DriSurface::SwapBuffers() {
......
......@@ -32,6 +32,7 @@ class DriSurface : public ScanoutSurface {
virtual bool Initialize() OVERRIDE;
virtual uint32_t GetFramebufferId() const OVERRIDE;
virtual uint32_t GetHandle() const OVERRIDE;
virtual void PreSwapBuffers() OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
virtual gfx::Size Size() const OVERRIDE;
......
......@@ -87,7 +87,7 @@ void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) {
return;
UpdateNativeSurface(damage);
controller_->SchedulePageFlip();
controller_->SchedulePageFlip(std::vector<OzoneOverlayPlane>(), NULL);
controller_->WaitForPageFlipEvent();
}
......
......@@ -12,6 +12,12 @@
#include "base/logging.h"
namespace ui {
namespace {
uint32_t ToFixedPoint(double v) {
// This returns a number in a 16-bit.16-bit fixed point.
return v * 65536.0;
}
} // namespace
DriWrapper::DriWrapper(const char* device_path) {
fd_ = open(device_path, O_RDWR | O_CLOEXEC);
......@@ -86,6 +92,27 @@ bool DriWrapper::PageFlip(uint32_t crtc_id,
data);
}
bool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
uint32_t framebuffer,
const gfx::Rect& location,
const gfx::RectF& source,
int overlay_plane) {
CHECK(fd_ >= 0);
return !drmModeSetPlane(fd_,
overlay_plane,
crtc_id,
framebuffer,
0,
location.x(),
location.y(),
location.width(),
location.height(),
ToFixedPoint(source.x()),
ToFixedPoint(source.y()),
ToFixedPoint(source.width()),
ToFixedPoint(source.height()));
}
ScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) {
CHECK(fd_ >= 0);
return ScopedDrmFramebufferPtr(drmModeGetFB(fd_, framebuffer));
......
......@@ -8,6 +8,9 @@
#include <stdint.h>
#include "base/macros.h"
#include "ui/gfx/overlay_transform.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/rect_f.h"
#include "ui/ozone/platform/dri/scoped_drm_types.h"
typedef struct _drmEventContext drmEventContext;
......@@ -67,6 +70,15 @@ class DriWrapper {
// will receive when processing the pageflip event.
virtual bool PageFlip(uint32_t crtc_id, uint32_t framebuffer, void* data);
// Schedule an overlay to be show during the page flip for CRTC |crtc_id|.
// |source| location from |framebuffer| will be shown on overlay
// |overlay_plane|, in the bounds specified by |location| on the screen.
virtual bool PageFlipOverlay(uint32_t crtc_id,
uint32_t framebuffer,
const gfx::Rect& location,
const gfx::RectF& source,
int overlay_plane);
// Returns the property with name |name| associated with |connector|. Returns
// NULL if property not found. If the returned value is valid, it must be
// released using FreeProperty().
......
......@@ -79,11 +79,40 @@ bool GbmBuffer::InitializeBuffer(SurfaceFactoryOzone::BufferFormat format,
return true;
}
void* GbmBuffer::GetEGLClientBuffer() {
return bo_;
bool GbmBuffer::Initialize() {
return bo_ != NULL;
}
int GbmBuffer::GetDmaBufFd() {
uint32_t GbmBuffer::GetFramebufferId() const {
return framebuffer_;
}
uint32_t GbmBuffer::GetHandle() const {
return handle_;
}
gfx::Size GbmBuffer::Size() const {
return size_;
}
void GbmBuffer::PreSwapBuffers() {
}
void GbmBuffer::SwapBuffers() {
}
GbmPixmap::GbmPixmap(gbm_device* device, DriWrapper* dri, const gfx::Size& size)
: buffer_(device, dri, size) {
}
GbmPixmap::~GbmPixmap() {
}
void* GbmPixmap::GetEGLClientBuffer() {
return buffer_.bo();
}
int GbmPixmap::GetDmaBufFd() {
return -1;
}
......
......@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/dri/scanout_surface.h"
#include "ui/ozone/public/native_pixmap.h"
#include "ui/ozone/public/surface_factory_ozone.h"
......@@ -18,18 +19,22 @@ namespace ui {
class DriWrapper;
class GbmBuffer : public NativePixmap {
class GbmBuffer : public ScanoutSurface {
public:
GbmBuffer(gbm_device* device, DriWrapper* dri, const gfx::Size& size);
virtual ~GbmBuffer();
bool InitializeBuffer(SurfaceFactoryOzone::BufferFormat format, bool scanout);
// NativePixmap:
virtual void* GetEGLClientBuffer() OVERRIDE;
virtual int GetDmaBufFd() OVERRIDE;
// ScanoutSurface:
virtual bool Initialize() OVERRIDE;
virtual uint32_t GetFramebufferId() const OVERRIDE;
virtual uint32_t GetHandle() const OVERRIDE;
virtual gfx::Size Size() const OVERRIDE;
virtual void PreSwapBuffers() OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
protected:
virtual ~GbmBuffer();
gbm_bo* bo() { return bo_; }
private:
gbm_device* gbm_device_;
......@@ -43,6 +48,21 @@ class GbmBuffer : public NativePixmap {
gfx::Size size_;
};
class GbmPixmap : public NativePixmap {
public:
GbmPixmap(gbm_device* device, DriWrapper* dri, const gfx::Size& size);
virtual ~GbmPixmap();
// NativePixmap:
virtual void* GetEGLClientBuffer() OVERRIDE;
virtual int GetDmaBufFd() OVERRIDE;
GbmBuffer* buffer() { return &buffer_; }
private:
GbmBuffer buffer_;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_DRI_GBM_BUFFER_H_
......@@ -81,20 +81,13 @@ gfx::Size GbmSurface::Size() const {
return size_;
}
void GbmSurface::SwapBuffers() {
// If there was a frontbuffer, is no longer active. Release it back to GBM.
if (buffers_[front_buffer_])
gbm_surface_release_buffer(native_surface_, buffers_[front_buffer_]);
// Update the index to the frontbuffer.
front_buffer_ ^= 1;
// We've just released it. Since GBM doesn't guarantee we'll get the same
// buffer back, we set it to NULL so we don't keep track of objects that may
// have been destroyed.
buffers_[front_buffer_ ^ 1] = NULL;
}
void GbmSurface::LockCurrentDrawable() {
// Before scheduling the backbuffer to be scanned out we need to "lock" it.
// When we lock it, GBM will give a pointer to a buffer representing the
// backbuffer. It will also update its information on which buffers can not be
// used for drawing. The buffer will be released when the page flip event
// occurs (see SwapBuffers). This is called from HardwareDisplayController
// before scheduling a page flip.
void GbmSurface::PreSwapBuffers() {
CHECK(native_surface_);
// Lock the buffer we want to display.
buffers_[front_buffer_ ^ 1] = gbm_surface_lock_front_buffer(native_surface_);
......@@ -109,4 +102,17 @@ void GbmSurface::LockCurrentDrawable() {
}
}
void GbmSurface::SwapBuffers() {
// If there was a frontbuffer, is no longer active. Release it back to GBM.
if (buffers_[front_buffer_])
gbm_surface_release_buffer(native_surface_, buffers_[front_buffer_]);
// Update the index to the frontbuffer.
front_buffer_ ^= 1;
// We've just released it. Since GBM doesn't guarantee we'll get the same
// buffer back, we set it to NULL so we don't keep track of objects that may
// have been destroyed.
buffers_[front_buffer_ ^ 1] = NULL;
}
} // namespace ui
......@@ -32,16 +32,9 @@ class GbmSurface : public ScanoutSurface {
virtual uint32_t GetFramebufferId() const OVERRIDE;
virtual uint32_t GetHandle() const OVERRIDE;
virtual gfx::Size Size() const OVERRIDE;
virtual void PreSwapBuffers() OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
// Before scheduling the backbuffer to be scanned out we need to "lock" it.
// When we lock it, GBM will give a pointer to a buffer representing the
// backbuffer. It will also update its information on which buffers can not be
// used for drawing. The buffer will be released when the page flip event
// occurs (see SwapBuffers). This is called from GbmSurfaceFactory before
// scheduling a page flip.
void LockCurrentDrawable();
gbm_surface* native_surface() { return native_surface_; };
private:
......
......@@ -15,6 +15,7 @@
#include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/scanout_surface.h"
#include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/public/native_pixmap.h"
#include "ui/ozone/public/surface_ozone_egl.h"
namespace ui {
......@@ -39,6 +40,8 @@ class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL {
private:
base::WeakPtr<HardwareDisplayController> controller_;
NativePixmapList overlay_refs_;
std::vector<OzoneOverlayPlane> overlays_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceAdapter);
};
......@@ -65,24 +68,32 @@ bool GbmSurfaceAdapter::ResizeNativeWindow(const gfx::Size& viewport_size) {
bool GbmSurfaceAdapter::OnSwapBuffers() {
if (!controller_)
return false;
static_cast<GbmSurface*>(controller_->surface())->LockCurrentDrawable();
if (controller_->SchedulePageFlip()) {
bool flip_succeeded =
controller_->SchedulePageFlip(overlays_, &overlay_refs_);
overlays_.clear();
if (flip_succeeded)
controller_->WaitForPageFlipEvent();
return true;
}
return false;
return flip_succeeded;
}
bool GbmSurfaceAdapter::ScheduleOverlayPlane(
int plane_z_order,
gfx::OverlayTransform plane_transform,
scoped_refptr<ui::NativePixmap> buffer,
scoped_refptr<NativePixmap> buffer,
const gfx::Rect& display_bounds,
const gfx::RectF& crop_rect) {
NOTIMPLEMENTED();
GbmPixmap* pixmap = static_cast<GbmPixmap*>(buffer.get());
if (!pixmap) {
LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer";
return false;
}
overlays_.push_back(OzoneOverlayPlane(pixmap->buffer(),
plane_z_order,
plane_transform,
display_bounds,
crop_rect));
overlay_refs_.push_back(buffer);
return true;
}
scoped_ptr<gfx::VSyncProvider> GbmSurfaceAdapter::CreateVSyncProvider() {
......@@ -91,9 +102,11 @@ scoped_ptr<gfx::VSyncProvider> GbmSurfaceAdapter::CreateVSyncProvider() {
} // namespace
GbmSurfaceFactory::GbmSurfaceFactory()
GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless)
: DriSurfaceFactory(NULL, NULL),
device_(NULL) {}
device_(NULL),
allow_surfaceless_(allow_surfaceless) {
}
GbmSurfaceFactory::~GbmSurfaceFactory() {}
......@@ -176,11 +189,15 @@ scoped_ptr<ui::SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
gfx::Size size,
BufferFormat format) {
scoped_refptr<GbmBuffer> buf = new GbmBuffer(device_, drm_, size);
if (!buf->InitializeBuffer(format, true)) {
scoped_refptr<GbmPixmap> buf = new GbmPixmap(device_, drm_, size);
if (!buf->buffer()->InitializeBuffer(format, true)) {
return NULL;
}
return buf;
}
bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
return allow_surfaceless_;
}
} // namespace ui
......@@ -13,7 +13,7 @@ namespace ui {
class GbmSurfaceFactory : public DriSurfaceFactory {
public:
GbmSurfaceFactory();
GbmSurfaceFactory(bool allow_surfaceless);
virtual ~GbmSurfaceFactory();
void InitializeGpu(DriWrapper* dri,
......@@ -32,9 +32,11 @@ class GbmSurfaceFactory : public DriSurfaceFactory {
virtual scoped_refptr<ui::NativePixmap> CreateNativePixmap(
gfx::Size size,
BufferFormat format) OVERRIDE;
virtual bool CanShowPrimaryPlaneAsOverlay() OVERRIDE;
private:
gbm_device* device_; // Not owned.
bool allow_surfaceless_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceFactory);
};
......
......@@ -19,6 +19,7 @@
#include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/scanout_surface.h"
#include "ui/ozone/public/native_pixmap.h"
namespace ui {
......@@ -46,6 +47,19 @@ void HandlePageFlipEvent(int fd,
} // namespace
OzoneOverlayPlane::OzoneOverlayPlane(ScanoutSurface* scanout,
int z_order,
gfx::OverlayTransform plane_transform,
const gfx::Rect& display_bounds,
const gfx::RectF& crop_rect)
: scanout(scanout),
z_order(z_order),
plane_transform(plane_transform),
display_bounds(display_bounds),
crop_rect(crop_rect),
overlay_plane(0) {
}
HardwareDisplayController::HardwareDisplayController(
DriWrapper* drm,
uint32_t connector_id,
......@@ -112,15 +126,54 @@ void HardwareDisplayController::Disable() {
is_disabled_ = true;
}
bool HardwareDisplayController::SchedulePageFlip() {
CHECK(surface_);
if (!is_disabled_ && !drm_->PageFlip(crtc_id_,
surface_->GetFramebufferId(),
this)) {
ScanoutSurface* HardwareDisplayController::GetPrimaryPlane(
const std::vector<OzoneOverlayPlane>& overlays) {
ScanoutSurface* primary = surface_.get();
for (size_t i = 0; i < overlays.size(); i++) {
const OzoneOverlayPlane& plane = overlays[i];
if (plane.z_order == 0) {
return plane.scanout;
}
}
return primary;
}
bool HardwareDisplayController::SchedulePageFlip(
const std::vector<OzoneOverlayPlane>& overlays,
NativePixmapList* references) {
ScanoutSurface* primary = GetPrimaryPlane(overlays);
CHECK(primary);
primary->PreSwapBuffers();
if (!is_disabled_ &&
!drm_->PageFlip(crtc_id_, primary->GetFramebufferId(), this)) {
LOG(ERROR) << "Cannot page flip: " << strerror(errno);
return false;
}
current_overlay_references_.clear();
if (references)
current_overlay_references_.swap(*references);
for (size_t i = 0; i < overlays.size(); i++) {
const OzoneOverlayPlane& plane = overlays[i];
if (!plane.overlay_plane)
continue;
const gfx::Size& size = plane.scanout->Size();
gfx::RectF crop_rect = plane.crop_rect;
crop_rect.Scale(size.width(), size.height());
if (!drm_->PageFlipOverlay(crtc_id_,
plane.scanout->GetFramebufferId(),
plane.display_bounds,
crop_rect,
plane.overlay_plane)) {
LOG(ERROR) << "Cannot display on overlay: " << strerror(errno);
return false;
}
}
return true;
}
......
......@@ -21,8 +21,26 @@ class Point;
namespace ui {
class NativePixmap;
class ScanoutSurface;
typedef std::vector<scoped_refptr<NativePixmap> > NativePixmapList;
struct OzoneOverlayPlane {
OzoneOverlayPlane(ScanoutSurface* scanout,
int z_order,
gfx::OverlayTransform plane_transform,
const gfx::Rect& display_bounds,
const gfx::RectF& crop_rect);
ScanoutSurface* scanout;
int z_order;
gfx::OverlayTransform plane_transform;
gfx::Rect display_bounds;
gfx::RectF crop_rect;
int overlay_plane;
};
// The HDCOz will handle modesettings and scannout operations for hardware
// devices.
//
......@@ -114,7 +132,8 @@ class HardwareDisplayController
// called again before the page flip occurrs.
//
// Returns true if the page flip was successfully registered, false otherwise.
bool SchedulePageFlip();
bool SchedulePageFlip(const std::vector<OzoneOverlayPlane>& overlays,
NativePixmapList* references);
// TODO(dnicoara) This should be on the MessageLoop when Ozone can have
// BeginFrame can be triggered explicitly by Ozone.
......@@ -150,6 +169,11 @@ class HardwareDisplayController
};
private:
ScanoutSurface* GetPrimaryPlane(
const std::vector<OzoneOverlayPlane>& overlays);
NativePixmapList current_overlay_references_;
// Object containing the connection to the graphics device and wraps the API
// calls to control it.
DriWrapper* drm_;
......
......@@ -10,6 +10,7 @@
#include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/test/mock_dri_surface.h"
#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h"
#include "ui/ozone/public/native_pixmap.h"
namespace {
......@@ -18,6 +19,7 @@ const drmModeModeInfo kDefaultMode =
{0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay);
const gfx::SizeF kDefaultModeSizeF(1.0, 1.0);
} // namespace
......@@ -63,7 +65,8 @@ TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
EXPECT_TRUE(controller_->SchedulePageFlip());
EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL));
EXPECT_TRUE(controller_->surface() != NULL);
}
......@@ -88,7 +91,8 @@ TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) {
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
EXPECT_FALSE(controller_->SchedulePageFlip());
EXPECT_FALSE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL));
}
TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) {
......@@ -99,7 +103,8 @@ TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) {
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
controller_->Disable();
EXPECT_TRUE(controller_->SchedulePageFlip());
EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL));
EXPECT_EQ(0, drm_->get_page_flip_call_count());
surface.reset(new ui::MockDriSurface(drm_.get(), kDefaultModeSize));
......@@ -107,6 +112,58 @@ TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) {
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
EXPECT_TRUE(controller_->SchedulePageFlip());
EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL));
EXPECT_EQ(1, drm_->get_page_flip_call_count());
}
TEST_F(HardwareDisplayControllerTest, CheckOverlayMainSurfaceReplacement) {
scoped_ptr<ui::ScanoutSurface> surface(
new ui::MockDriSurface(drm_.get(), kDefaultModeSize));
scoped_ptr<ui::ScanoutSurface> overlay(
new ui::MockDriSurface(drm_.get(), kDefaultModeSize));
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(
controller_->BindSurfaceToController(surface.Pass(), kDefaultMode));
EXPECT_TRUE(overlay->Initialize());
std::vector<ui::OzoneOverlayPlane> overlays;
std::vector<scoped_refptr<ui::NativePixmap> > overlay_refs;
overlays.push_back(ui::OzoneOverlayPlane(overlay.get(),
0,
gfx::OVERLAY_TRANSFORM_NONE,
gfx::Rect(kDefaultModeSize),
gfx::RectF(kDefaultModeSizeF)));
EXPECT_TRUE(controller_->SchedulePageFlip(overlays, &overlay_refs));
EXPECT_EQ(1, drm_->get_page_flip_call_count());
EXPECT_EQ(0, drm_->get_overlay_flip_call_count());
}
TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) {
scoped_ptr<ui::ScanoutSurface> surface(
new ui::MockDriSurface(drm_.get(), kDefaultModeSize));
scoped_ptr<ui::ScanoutSurface> overlay(
new ui::MockDriSurface(drm_.get(), kDefaultModeSize));
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(
controller_->BindSurfaceToController(surface.Pass(), kDefaultMode));
EXPECT_TRUE(overlay->Initialize());
std::vector<ui::OzoneOverlayPlane> overlays;
std::vector<scoped_refptr<ui::NativePixmap> > overlay_refs;
overlays.push_back(ui::OzoneOverlayPlane(overlay.get(),
1,
gfx::OVERLAY_TRANSFORM_NONE,
gfx::Rect(kDefaultModeSize),
gfx::RectF(kDefaultModeSizeF)));
overlays.back().overlay_plane = 1; // Force association with a plane.
EXPECT_TRUE(controller_->SchedulePageFlip(overlays, &overlay_refs));
EXPECT_EQ(1, drm_->get_page_flip_call_count());
EXPECT_EQ(1, drm_->get_overlay_flip_call_count());
}
......@@ -13,6 +13,7 @@
#include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/ozone/platform/dri/cursor_factory_evdev_dri.h"
#include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/gbm_buffer.h"
#include "ui/ozone/platform/dri/gbm_surface.h"
#include "ui/ozone/platform/dri/gbm_surface_factory.h"
#include "ui/ozone/platform/dri/gpu_platform_support_gbm.h"
......@@ -56,7 +57,7 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator {
return new GbmSurface(device_, dri_, size);
}
private:
protected:
DriWrapper* dri_; // Not owned.
// HACK: gbm drivers have broken linkage
......@@ -67,9 +68,24 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator {
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceGenerator);
};
class GbmEglImageSurfaceGenerator : public GbmSurfaceGenerator {
public:
GbmEglImageSurfaceGenerator(DriWrapper* dri) : GbmSurfaceGenerator(dri) {}
virtual ~GbmEglImageSurfaceGenerator() {}
virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE {
scoped_ptr<GbmBuffer> buffer =
scoped_ptr<GbmBuffer>(new GbmBuffer(device_, dri_, size));
if (!buffer->InitializeBuffer(SurfaceFactoryOzone::RGBA_8888, true)) {
return NULL;
}
return buffer.release();
}
};
class OzonePlatformGbm : public OzonePlatform {
public:
OzonePlatformGbm() {
OzonePlatformGbm(bool use_surfaceless) : use_surfaceless_(use_surfaceless) {
base::AtExitManager::RegisterTask(
base::Bind(&base::DeletePointer<OzonePlatformGbm>, this));
}
......@@ -107,7 +123,7 @@ class OzonePlatformGbm : public OzonePlatform {
vt_manager_.reset(new VirtualTerminalManager());
// Needed since the browser process creates the accelerated widgets and that
// happens through SFO.
surface_factory_ozone_.reset(new GbmSurfaceFactory());
surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_));
device_manager_ = CreateDeviceManager();
gpu_platform_support_host_.reset(new GpuPlatformSupportHostGbm());
......@@ -119,11 +135,14 @@ class OzonePlatformGbm : public OzonePlatform {
virtual void InitializeGPU() OVERRIDE {
dri_.reset(new DriWrapper(kDefaultGraphicsCardPath));
if (use_surfaceless_)
surface_generator_.reset(new GbmEglImageSurfaceGenerator(dri_.get()));
else
surface_generator_.reset(new GbmSurfaceGenerator(dri_.get()));
screen_manager_.reset(new ScreenManager(dri_.get(),
surface_generator_.get()));
if (!surface_factory_ozone_)
surface_factory_ozone_.reset(new GbmSurfaceFactory());
surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_));
surface_factory_ozone_->InitializeGpu(dri_.get(),
surface_generator_->device(),
......@@ -142,6 +161,7 @@ class OzonePlatformGbm : public OzonePlatform {
}
private:
bool use_surfaceless_;
scoped_ptr<VirtualTerminalManager> vt_manager_;
scoped_ptr<DriWrapper> dri_;
scoped_ptr<GbmSurfaceGenerator> surface_generator_;
......@@ -160,6 +180,11 @@ class OzonePlatformGbm : public OzonePlatform {
} // namespace
OzonePlatform* CreateOzonePlatformGbm() { return new OzonePlatformGbm; }
OzonePlatform* CreateOzonePlatformGbm() {
return new OzonePlatformGbm(false);
}
OzonePlatform* CreateOzonePlatformGbmEglImage() {
return new OzonePlatformGbm(true);
}
} // namespace ui
......@@ -59,6 +59,9 @@ class ScanoutSurface {
// Returns true if the initialization is successful, false otherwise.
virtual bool Initialize() = 0;
// Prepare the surface to be displayed.
virtual void PreSwapBuffers() = 0;
// Swaps the back buffer with the front buffer.
virtual void SwapBuffers() = 0;
......
......@@ -27,6 +27,7 @@ MockDriWrapper::MockDriWrapper(int fd)
add_framebuffer_call_count_(0),
remove_framebuffer_call_count_(0),
page_flip_call_count_(0),
overlay_flip_call_count_(0),
set_crtc_expectation_(true),
add_framebuffer_expectation_(true),
page_flip_expectation_(true) {
......@@ -79,6 +80,15 @@ bool MockDriWrapper::PageFlip(uint32_t crtc_id,
return page_flip_expectation_;
}
bool MockDriWrapper::PageFlipOverlay(uint32_t crtc_id,
uint32_t framebuffer,
const gfx::Rect& location,
const gfx::RectF& source,
int overlay_plane) {
overlay_flip_call_count_++;
return true;
}
ScopedDrmPropertyPtr MockDriWrapper::GetProperty(drmModeConnector* connector,
const char* name) {
return ScopedDrmPropertyPtr(DrmAllocator<drmModePropertyRes>());
......
......@@ -24,6 +24,7 @@ class MockDriWrapper : public ui::DriWrapper {
return remove_framebuffer_call_count_;
}
int get_page_flip_call_count() const { return page_flip_call_count_; }
int get_overlay_flip_call_count() const { return overlay_flip_call_count_; }
void fail_init() { fd_ = -1; }
void set_set_crtc_expectation(bool state) { set_crtc_expectation_ = state; }
void set_page_flip_expectation(bool state) { page_flip_expectation_ = state; }
......@@ -49,6 +50,11 @@ class MockDriWrapper : public ui::DriWrapper {
virtual bool PageFlip(uint32_t crtc_id,
uint32_t framebuffer,
void* data) OVERRIDE;
virtual bool PageFlipOverlay(uint32_t crtc_id,
uint32_t framebuffer,
const gfx::Rect& location,
const gfx::RectF& source,
int overlay_plane) OVERRIDE;
virtual ScopedDrmPropertyPtr GetProperty(drmModeConnector* connector,
const char* name) OVERRIDE;
virtual bool SetProperty(uint32_t connector_id,
......@@ -69,6 +75,7 @@ class MockDriWrapper : public ui::DriWrapper {
int add_framebuffer_call_count_;
int remove_framebuffer_call_count_;
int page_flip_call_count_;
int overlay_flip_call_count_;
bool set_crtc_expectation_;
bool add_framebuffer_expectation_;
......
......@@ -52,8 +52,9 @@ class OZONE_BASE_EXPORT SurfaceOzoneEGL {
// composition.
// |buffer| to be presented by the overlay.
// |display_bounds| specify where it is supposed to be on the screen.
// |crop_rect| specifies the region within the buffer to be placed inside
// |display_bounds|.
// |crop_rect| specifies the region within the buffer to be placed
// inside |display_bounds|. This is specified in texture coordinates, in the
// range of [0,1].
virtual bool ScheduleOverlayPlane(int plane_z_order,
gfx::OverlayTransform plane_transform,
scoped_refptr<NativePixmap> buffer,
......
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