Skip to content

Commit

Permalink
ozone: gbm: Add overlay support
Browse files Browse the repository at this point in the history
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
  • Loading branch information
achaulk@chromium.org committed Jul 11, 2014
1 parent e7cd231 commit 055f8f2
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 65 deletions.
3 changes: 3 additions & 0 deletions ui/ozone/platform/dri/dri_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions ui/ozone/platform/dri/dri_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion ui/ozone/platform/dri/dri_surface_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) {
return;

UpdateNativeSurface(damage);
controller_->SchedulePageFlip();
controller_->SchedulePageFlip(std::vector<OzoneOverlayPlane>(), NULL);
controller_->WaitForPageFlipEvent();
}

Expand Down
27 changes: 27 additions & 0 deletions ui/ozone/platform/dri/dri_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down
12 changes: 12 additions & 0 deletions ui/ozone/platform/dri/dri_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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().
Expand Down
35 changes: 32 additions & 3 deletions ui/ozone/platform/dri/gbm_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
32 changes: 26 additions & 6 deletions ui/ozone/platform/dri/gbm_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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_;
Expand All @@ -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_
34 changes: 20 additions & 14 deletions ui/ozone/platform/dri/gbm_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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_);
Expand All @@ -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
9 changes: 1 addition & 8 deletions ui/ozone/platform/dri/gbm_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
45 changes: 31 additions & 14 deletions ui/ozone/platform/dri/gbm_surface_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
};
Expand All @@ -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();
return false;
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() {
Expand All @@ -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() {}

Expand Down Expand Up @@ -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
4 changes: 3 additions & 1 deletion ui/ozone/platform/dri/gbm_surface_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ui {

class GbmSurfaceFactory : public DriSurfaceFactory {
public:
GbmSurfaceFactory();
GbmSurfaceFactory(bool allow_surfaceless);
virtual ~GbmSurfaceFactory();

void InitializeGpu(DriWrapper* dri,
Expand All @@ -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);
};
Expand Down
Loading

0 comments on commit 055f8f2

Please sign in to comment.