Commit 60ffa235 authored by dnicoara@chromium.org's avatar dnicoara@chromium.org

[Ozone-DRI] Convert HardwareDisplayController to use scanout buffers

This change allows scanout buffers to be kept alive until the last of
SurfaceOzone{Canvas,EGL} and HardwareDisplayController are destroyed. For
HardwareDisplayController this means that buffers will be kept around
until the CRTC is properly restored. For SurfaceOzoneEGL this means that
on monitor disconnects (HDC is destroyed) the buffers are kept alive for
any remaining EGL operations still happening.

BUG=none
NOTRY=true

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284708 0039d316-1c4b-4281-b951-d872f2087c98
parent 882d4786
...@@ -101,8 +101,6 @@ ...@@ -101,8 +101,6 @@
'screen_manager_unittest.cc', 'screen_manager_unittest.cc',
'test/mock_dri_wrapper.cc', 'test/mock_dri_wrapper.cc',
'test/mock_dri_wrapper.h', 'test/mock_dri_wrapper.h',
'test/mock_surface_generator.cc',
'test/mock_surface_generator.h',
], ],
}, },
}, },
......
...@@ -60,7 +60,6 @@ void DriSurface::PreSwapBuffers() { ...@@ -60,7 +60,6 @@ void DriSurface::PreSwapBuffers() {
// This call is made after the hardware just started displaying our back buffer. // 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. // We need to update our pointer reference and synchronize the two buffers.
void DriSurface::SwapBuffers() { void DriSurface::SwapBuffers() {
CHECK(frontbuffer());
CHECK(backbuffer()); CHECK(backbuffer());
// Update our front buffer pointer. // Update our front buffer pointer.
......
...@@ -27,6 +27,9 @@ class DriSurface : public ScanoutSurface { ...@@ -27,6 +27,9 @@ class DriSurface : public ScanoutSurface {
// Get a Skia canvas for a backbuffer. // Get a Skia canvas for a backbuffer.
SkCanvas* GetDrawableForWidget(); SkCanvas* GetDrawableForWidget();
scoped_refptr<DriBuffer> backbuffer() const {
return bitmaps_[front_buffer_ ^ 1];
}
// ScanoutSurface: // ScanoutSurface:
virtual bool Initialize() OVERRIDE; virtual bool Initialize() OVERRIDE;
...@@ -37,9 +40,6 @@ class DriSurface : public ScanoutSurface { ...@@ -37,9 +40,6 @@ class DriSurface : public ScanoutSurface {
virtual gfx::Size Size() const OVERRIDE; virtual gfx::Size Size() const OVERRIDE;
private: private:
DriBuffer* frontbuffer() const { return bitmaps_[front_buffer_].get(); }
DriBuffer* backbuffer() const { return bitmaps_[front_buffer_ ^ 1].get(); }
// Stores the connection to the graphics card. Pointer not owned by this // Stores the connection to the graphics card. Pointer not owned by this
// class. // class.
DriWrapper* dri_; DriWrapper* dri_;
......
...@@ -45,7 +45,8 @@ void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) { ...@@ -45,7 +45,8 @@ void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) {
class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas { class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas {
public: public:
DriSurfaceAdapter(const base::WeakPtr<HardwareDisplayController>& controller); DriSurfaceAdapter(DriWrapper* dri,
const base::WeakPtr<HardwareDisplayController>& controller);
virtual ~DriSurfaceAdapter(); virtual ~DriSurfaceAdapter();
// SurfaceOzoneCanvas: // SurfaceOzoneCanvas:
...@@ -57,6 +58,8 @@ class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas { ...@@ -57,6 +58,8 @@ class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas {
private: private:
void UpdateNativeSurface(const gfx::Rect& damage); void UpdateNativeSurface(const gfx::Rect& damage);
DriWrapper* dri_;
scoped_ptr<DriSurface> native_surface_;
skia::RefPtr<SkSurface> surface_; skia::RefPtr<SkSurface> surface_;
gfx::Rect last_damage_; gfx::Rect last_damage_;
base::WeakPtr<HardwareDisplayController> controller_; base::WeakPtr<HardwareDisplayController> controller_;
...@@ -65,8 +68,9 @@ class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas { ...@@ -65,8 +68,9 @@ class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas {
}; };
DriSurfaceAdapter::DriSurfaceAdapter( DriSurfaceAdapter::DriSurfaceAdapter(
DriWrapper* dri,
const base::WeakPtr<HardwareDisplayController>& controller) const base::WeakPtr<HardwareDisplayController>& controller)
: controller_(controller) { : dri_(dri), controller_(controller) {
} }
DriSurfaceAdapter::~DriSurfaceAdapter() { DriSurfaceAdapter::~DriSurfaceAdapter() {
...@@ -80,6 +84,16 @@ void DriSurfaceAdapter::ResizeCanvas(const gfx::Size& viewport_size) { ...@@ -80,6 +84,16 @@ void DriSurfaceAdapter::ResizeCanvas(const gfx::Size& viewport_size) {
SkImageInfo info = SkImageInfo::MakeN32( SkImageInfo info = SkImageInfo::MakeN32(
viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType); viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType);
surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); surface_ = skia::AdoptRef(SkSurface::NewRaster(info));
if (controller_) {
// Need to use the mode size rather than |viewport_size| since a display
// cannot scanout from a buffer smaller than the mode.
native_surface_.reset(
new DriSurface(dri_,
gfx::Size(controller_->get_mode().hdisplay,
controller_->get_mode().vdisplay)));
CHECK(native_surface_->Initialize());
}
} }
void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) { void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) {
...@@ -88,8 +102,10 @@ void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) { ...@@ -88,8 +102,10 @@ void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) {
return; return;
UpdateNativeSurface(damage); UpdateNativeSurface(damage);
controller_->SchedulePageFlip(std::vector<OzoneOverlayPlane>(), NULL); controller_->SchedulePageFlip(std::vector<OverlayPlane>(
1, OverlayPlane(native_surface_->backbuffer())));
controller_->WaitForPageFlipEvent(); controller_->WaitForPageFlipEvent();
native_surface_->SwapBuffers();
} }
scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() { scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() {
...@@ -97,8 +113,7 @@ scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() { ...@@ -97,8 +113,7 @@ scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() {
} }
void DriSurfaceAdapter::UpdateNativeSurface(const gfx::Rect& damage) { void DriSurfaceAdapter::UpdateNativeSurface(const gfx::Rect& damage) {
SkCanvas* canvas = static_cast<DriSurface*>(controller_->surface()) SkCanvas* canvas = native_surface_->GetDrawableForWidget();
->GetDrawableForWidget();
// The DriSurface is double buffered, so the current back buffer is // The DriSurface is double buffered, so the current back buffer is
// missing the previous update. Expand damage region. // missing the previous update. Expand damage region.
...@@ -175,7 +190,7 @@ scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget( ...@@ -175,7 +190,7 @@ scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget(
ResetCursor(w); ResetCursor(w);
return scoped_ptr<ui::SurfaceOzoneCanvas>( return scoped_ptr<ui::SurfaceOzoneCanvas>(
new DriSurfaceAdapter(screen_manager_->GetDisplayController(w))); new DriSurfaceAdapter(drm_, screen_manager_->GetDisplayController(w)));
} }
bool DriSurfaceFactory::LoadEGLGLES2Bindings( bool DriSurfaceFactory::LoadEGLGLES2Bindings(
......
...@@ -16,20 +16,20 @@ ...@@ -16,20 +16,20 @@
#include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h"
#include "ui/ozone/platform/dri/test/mock_surface_generator.h"
#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_factory_ozone.h"
#include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_canvas.h"
namespace { namespace {
// Mode of size 6x4.
const drmModeModeInfo kDefaultMode = const drmModeModeInfo kDefaultMode =
{0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
class MockScreenManager : public ui::ScreenManager { class MockScreenManager : public ui::ScreenManager {
public: public:
MockScreenManager(ui::DriWrapper* dri, MockScreenManager(ui::DriWrapper* dri,
ui::ScanoutSurfaceGenerator* surface_generator) ui::ScanoutBufferGenerator* buffer_generator)
: ScreenManager(dri, surface_generator), : ScreenManager(dri, buffer_generator),
dri_(dri) {} dri_(dri) {}
virtual ~MockScreenManager() {} virtual ~MockScreenManager() {}
...@@ -56,7 +56,7 @@ class DriSurfaceFactoryTest : public testing::Test { ...@@ -56,7 +56,7 @@ class DriSurfaceFactoryTest : public testing::Test {
protected: protected:
scoped_ptr<base::MessageLoop> message_loop_; scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<ui::MockDriWrapper> dri_; scoped_ptr<ui::MockDriWrapper> dri_;
scoped_ptr<ui::MockSurfaceGenerator> surface_generator_; scoped_ptr<ui::DriBufferGenerator> buffer_generator_;
scoped_ptr<MockScreenManager> screen_manager_; scoped_ptr<MockScreenManager> screen_manager_;
scoped_ptr<ui::DriSurfaceFactory> factory_; scoped_ptr<ui::DriSurfaceFactory> factory_;
...@@ -67,9 +67,9 @@ class DriSurfaceFactoryTest : public testing::Test { ...@@ -67,9 +67,9 @@ class DriSurfaceFactoryTest : public testing::Test {
void DriSurfaceFactoryTest::SetUp() { void DriSurfaceFactoryTest::SetUp() {
message_loop_.reset(new base::MessageLoopForUI); message_loop_.reset(new base::MessageLoopForUI);
dri_.reset(new ui::MockDriWrapper(3)); dri_.reset(new ui::MockDriWrapper(3));
surface_generator_.reset(new ui::MockSurfaceGenerator(dri_.get())); buffer_generator_.reset(new ui::DriBufferGenerator(dri_.get()));
screen_manager_.reset(new MockScreenManager(dri_.get(), screen_manager_.reset(new MockScreenManager(dri_.get(),
surface_generator_.get())); buffer_generator_.get()));
factory_.reset(new ui::DriSurfaceFactory(dri_.get(), screen_manager_.get())); factory_.reset(new ui::DriSurfaceFactory(dri_.get(), screen_manager_.get()));
} }
...@@ -120,11 +120,12 @@ TEST_F(DriSurfaceFactoryTest, CheckNativeSurfaceContents) { ...@@ -120,11 +120,12 @@ TEST_F(DriSurfaceFactoryTest, CheckNativeSurfaceContents) {
gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2)); gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2));
SkBitmap image; SkBitmap image;
// Buffers 0 and 1 are the cursor buffers and 2 and 3 are the surface buffers. // Buffers 0 and 1 are the cursor buffers, 2 is the modeset buffer, and
// Buffer 3 is the backbuffer we just painted in, so we want to make sure its // 3 and 4 are the surface buffers.
// Buffer 4 is the backbuffer we just painted in, so we want to make sure its
// contents are correct. // contents are correct.
image.setInfo(dri_->buffers()[3]->getCanvas()->imageInfo()); image.setInfo(dri_->buffers()[4]->getCanvas()->imageInfo());
EXPECT_TRUE(dri_->buffers()[3]->getCanvas()->readPixels(&image, 0, 0)); EXPECT_TRUE(dri_->buffers()[4]->getCanvas()->readPixels(&image, 0, 0));
EXPECT_EQ(kDefaultMode.hdisplay, image.width()); EXPECT_EQ(kDefaultMode.hdisplay, image.width());
EXPECT_EQ(kDefaultMode.vdisplay, image.height()); EXPECT_EQ(kDefaultMode.vdisplay, image.height());
......
...@@ -60,15 +60,13 @@ TEST_F(DriSurfaceTest, SuccessfulInitialization) { ...@@ -60,15 +60,13 @@ TEST_F(DriSurfaceTest, SuccessfulInitialization) {
TEST_F(DriSurfaceTest, CheckFBIDOnSwap) { TEST_F(DriSurfaceTest, CheckFBIDOnSwap) {
EXPECT_TRUE(surface_->Initialize()); EXPECT_TRUE(surface_->Initialize());
controller_->BindSurfaceToController(surface_.PassAs<ui::ScanoutSurface>(),
kDefaultMode);
// Check that the framebuffer ID is correct. // Check that the framebuffer ID is correct.
EXPECT_EQ(2u, controller_->surface()->GetFramebufferId()); EXPECT_EQ(2u, surface_->GetFramebufferId());
controller_->surface()->SwapBuffers(); surface_->SwapBuffers();
EXPECT_EQ(1u, controller_->surface()->GetFramebufferId()); EXPECT_EQ(1u, surface_->GetFramebufferId());
} }
TEST_F(DriSurfaceTest, CheckPixelPointerOnSwap) { TEST_F(DriSurfaceTest, CheckPixelPointerOnSwap) {
......
...@@ -7,16 +7,10 @@ ...@@ -7,16 +7,10 @@
#include <gbm.h> #include <gbm.h>
#include "base/logging.h" #include "base/logging.h"
#include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h"
namespace ui { namespace ui {
namespace { namespace {
// Pixel configuration for the current buffer format.
// TODO(dnicoara) These will need to change once we query the hardware for
// supported configurations.
const uint8_t kColorDepth = 24;
const uint8_t kPixelDepth = 32;
int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) { int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) {
switch (fmt) { switch (fmt) {
...@@ -32,87 +26,55 @@ int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) { ...@@ -32,87 +26,55 @@ int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) {
} }
return 0; return 0;
} }
}
GbmBuffer::GbmBuffer(gbm_device* device, DriWrapper* dri, const gfx::Size& size) } // namespace
: gbm_device_(device),
bo_(NULL), GbmBuffer::GbmBuffer(DriWrapper* dri, gbm_bo* bo, bool scanout)
handle_(0), : GbmBufferBase(dri, bo, scanout) {
framebuffer_(0),
dri_(dri),
size_(size) {
} }
GbmBuffer::~GbmBuffer() { GbmBuffer::~GbmBuffer() {
if (framebuffer_) if (bo())
dri_->RemoveFramebuffer(framebuffer_); gbm_bo_destroy(bo());
if (bo_)
gbm_bo_destroy(bo_);
} }
bool GbmBuffer::InitializeBuffer(SurfaceFactoryOzone::BufferFormat format, // static
bool scanout) { scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer(
DriWrapper* dri,
gbm_device* device,
SurfaceFactoryOzone::BufferFormat format,
const gfx::Size& size,
bool scanout) {
unsigned flags = GBM_BO_USE_RENDERING; unsigned flags = GBM_BO_USE_RENDERING;
if (scanout) if (scanout)
flags |= GBM_BO_USE_SCANOUT; flags |= GBM_BO_USE_SCANOUT;
bo_ = gbm_bo_create(gbm_device_, gbm_bo* bo = gbm_bo_create(device,
size_.width(), size.width(),
size_.height(), size.height(),
GetGbmFormatFromBufferFormat(format), GetGbmFormatFromBufferFormat(format),
flags); flags);
if (!bo_) if (!bo)
return false; return NULL;
gbm_bo_set_user_data(bo_, this, NULL); scoped_refptr<GbmBuffer> buffer(new GbmBuffer(dri, bo, scanout));
handle_ = gbm_bo_get_handle(bo_).u32; if (scanout && !buffer->GetFramebufferId())
return NULL;
if (scanout &&
!dri_->AddFramebuffer(size_.width(), return buffer;
size_.height(),
kColorDepth,
kPixelDepth,
gbm_bo_get_stride(bo_),
handle_,
&framebuffer_)) {
return false;
}
return true;
}
bool GbmBuffer::Initialize() {
return bo_ != NULL;
}
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) GbmPixmap::GbmPixmap(scoped_refptr<GbmBuffer> buffer) : buffer_(buffer) {
: buffer_(device, dri, size) {
} }
GbmPixmap::~GbmPixmap() { GbmPixmap::~GbmPixmap() {
} }
void* GbmPixmap::GetEGLClientBuffer() { void* GbmPixmap::GetEGLClientBuffer() {
return buffer_.bo(); return buffer_->bo();
} }
int GbmPixmap::GetDmaBufFd() { int GbmPixmap::GetDmaBufFd() {
NOTIMPLEMENTED();
return -1; return -1;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/dri/scanout_surface.h" #include "ui/ozone/platform/dri/gbm_buffer_base.h"
#include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/native_pixmap.h"
#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_factory_ozone.h"
...@@ -19,49 +19,38 @@ namespace ui { ...@@ -19,49 +19,38 @@ namespace ui {
class DriWrapper; class DriWrapper;
class GbmBuffer : public ScanoutSurface { class GbmBuffer : public GbmBufferBase {
public: public:
GbmBuffer(gbm_device* device, DriWrapper* dri, const gfx::Size& size); static scoped_refptr<GbmBuffer> CreateBuffer(
virtual ~GbmBuffer(); DriWrapper* dri,
gbm_device* device,
bool InitializeBuffer(SurfaceFactoryOzone::BufferFormat format, bool scanout); SurfaceFactoryOzone::BufferFormat format,
const gfx::Size& size,
// ScanoutSurface: bool scanout);
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;
gbm_bo* bo() { return bo_; }
private: private:
gbm_device* gbm_device_; GbmBuffer(DriWrapper* dri, gbm_bo* bo, bool scanout);
gbm_bo* bo_; virtual ~GbmBuffer();
uint32_t handle_;
uint32_t framebuffer_;
DriWrapper* dri_;
gfx::Size size_; DISALLOW_COPY_AND_ASSIGN(GbmBuffer);
}; };
class GbmPixmap : public NativePixmap { class GbmPixmap : public NativePixmap {
public: public:
GbmPixmap(gbm_device* device, DriWrapper* dri, const gfx::Size& size); GbmPixmap(scoped_refptr<GbmBuffer> buffer);
// NativePixmap: // NativePixmap:
virtual void* GetEGLClientBuffer() OVERRIDE; virtual void* GetEGLClientBuffer() OVERRIDE;
virtual int GetDmaBufFd() OVERRIDE; virtual int GetDmaBufFd() OVERRIDE;
GbmBuffer* buffer() { return &buffer_; } scoped_refptr<GbmBuffer> buffer() { return buffer_; }
private: private:
virtual ~GbmPixmap(); virtual ~GbmPixmap();
GbmBuffer buffer_; scoped_refptr<GbmBuffer> buffer_;
DISALLOW_COPY_AND_ASSIGN(GbmPixmap);
}; };
} // namespace ui } // namespace ui
......
...@@ -28,6 +28,10 @@ class GbmSurface : public ScanoutSurface { ...@@ -28,6 +28,10 @@ class GbmSurface : public ScanoutSurface {
GbmSurface(gbm_device* device, DriWrapper* dri, const gfx::Size& size); GbmSurface(gbm_device* device, DriWrapper* dri, const gfx::Size& size);
virtual ~GbmSurface(); virtual ~GbmSurface();
scoped_refptr<GbmBufferBase> backbuffer() const {
return buffers_[front_buffer_ ^ 1];
}
// ScanoutSurface: // ScanoutSurface:
virtual bool Initialize() OVERRIDE; virtual bool Initialize() OVERRIDE;
virtual uint32_t GetFramebufferId() const OVERRIDE; virtual uint32_t GetFramebufferId() const OVERRIDE;
......
...@@ -23,9 +23,14 @@ namespace { ...@@ -23,9 +23,14 @@ namespace {
class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL { class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL {
public: public:
GbmSurfaceAdapter(const base::WeakPtr<HardwareDisplayController>& controller); GbmSurfaceAdapter(
gbm_device* device,
DriWrapper* dri,
const base::WeakPtr<HardwareDisplayController>& controller);
virtual ~GbmSurfaceAdapter(); virtual ~GbmSurfaceAdapter();
bool Initialize();
// SurfaceOzoneEGL: // SurfaceOzoneEGL:
virtual intptr_t GetNativeWindow() OVERRIDE; virtual intptr_t GetNativeWindow() OVERRIDE;
virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE; virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE;
...@@ -38,40 +43,64 @@ class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL { ...@@ -38,40 +43,64 @@ class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL {
const gfx::RectF& crop_rect) OVERRIDE; const gfx::RectF& crop_rect) OVERRIDE;
private: private:
gbm_device* device_;
DriWrapper* dri_;
scoped_ptr<GbmSurface> surface_;
base::WeakPtr<HardwareDisplayController> controller_; base::WeakPtr<HardwareDisplayController> controller_;
NativePixmapList overlay_refs_; OverlayPlaneList overlays_;
std::vector<OzoneOverlayPlane> overlays_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceAdapter); DISALLOW_COPY_AND_ASSIGN(GbmSurfaceAdapter);
}; };
GbmSurfaceAdapter::GbmSurfaceAdapter( GbmSurfaceAdapter::GbmSurfaceAdapter(
gbm_device* device,
DriWrapper* dri,
const base::WeakPtr<HardwareDisplayController>& controller) const base::WeakPtr<HardwareDisplayController>& controller)
: controller_(controller) {} : device_(device), dri_(dri), controller_(controller) {}
GbmSurfaceAdapter::~GbmSurfaceAdapter() {} GbmSurfaceAdapter::~GbmSurfaceAdapter() {}
bool GbmSurfaceAdapter::Initialize() {
if (controller_) {
surface_.reset(
new GbmSurface(device_,
dri_,
gfx::Size(controller_->get_mode().hdisplay,
controller_->get_mode().vdisplay)));
return surface_->Initialize();
}
return false;
}
intptr_t GbmSurfaceAdapter::GetNativeWindow() { intptr_t GbmSurfaceAdapter::GetNativeWindow() {
if (!controller_) if (!controller_)
return 0; return 0;
return reinterpret_cast<intptr_t>( return reinterpret_cast<intptr_t>(surface_->native_surface());
static_cast<GbmSurface*>(controller_->surface())->native_surface());
} }
bool GbmSurfaceAdapter::ResizeNativeWindow(const gfx::Size& viewport_size) { bool GbmSurfaceAdapter::ResizeNativeWindow(const gfx::Size& viewport_size) {
NOTIMPLEMENTED();
return false; return true;
} }
bool GbmSurfaceAdapter::OnSwapBuffers() { bool GbmSurfaceAdapter::OnSwapBuffers() {
if (!controller_) if (!controller_)
return false; return false;
bool flip_succeeded = if (surface_) {
controller_->SchedulePageFlip(overlays_, &overlay_refs_); surface_->PreSwapBuffers();
overlays_.push_back(OverlayPlane(surface_->backbuffer()));
}
bool flip_succeeded = controller_->SchedulePageFlip(overlays_);
overlays_.clear(); overlays_.clear();
if (flip_succeeded) if (flip_succeeded)
controller_->WaitForPageFlipEvent(); controller_->WaitForPageFlipEvent();
if (surface_)
surface_->SwapBuffers();
return flip_succeeded; return flip_succeeded;
} }
...@@ -86,12 +115,11 @@ bool GbmSurfaceAdapter::ScheduleOverlayPlane( ...@@ -86,12 +115,11 @@ bool GbmSurfaceAdapter::ScheduleOverlayPlane(
LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer"; LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer";
return false; return false;
} }
overlays_.push_back(OzoneOverlayPlane(pixmap->buffer(), overlays_.push_back(OverlayPlane(pixmap->buffer(),
plane_z_order, plane_z_order,
plane_transform, plane_transform,
display_bounds, display_bounds,
crop_rect)); crop_rect));
overlay_refs_.push_back(buffer);
return true; return true;
} }
...@@ -181,18 +209,25 @@ scoped_ptr<ui::SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget( ...@@ -181,18 +209,25 @@ scoped_ptr<ui::SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
CHECK(state_ == INITIALIZED); CHECK(state_ == INITIALIZED);
ResetCursor(w); ResetCursor(w);
return scoped_ptr<ui::SurfaceOzoneEGL>( scoped_ptr<GbmSurfaceAdapter> surface(
new GbmSurfaceAdapter(screen_manager_->GetDisplayController(w))); new GbmSurfaceAdapter(device_,
drm_,
screen_manager_->GetDisplayController(w)));
if (!allow_surfaceless_ && !surface->Initialize())
return scoped_ptr<SurfaceOzoneEGL>();
return surface.PassAs<SurfaceOzoneEGL>();
} }
scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
gfx::Size size, gfx::Size size,
BufferFormat format) { BufferFormat format) {
scoped_refptr<GbmPixmap> buf = new GbmPixmap(device_, drm_, size); scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer(
if (!buf->buffer()->InitializeBuffer(format, true)) { drm_, device_, format, size, true);
if (!buffer)
return NULL; return NULL;
}
return buf; return scoped_refptr<GbmPixmap>(new GbmPixmap(buffer));
} }
bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() { bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/scanout_surface.h"
#include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/native_pixmap.h"
namespace ui { namespace ui {
...@@ -45,14 +44,31 @@ void HandlePageFlipEvent(int fd, ...@@ -45,14 +44,31 @@ void HandlePageFlipEvent(int fd,
->OnPageFlipEvent(frame, seconds, useconds); ->OnPageFlipEvent(frame, seconds, useconds);
} }
const OverlayPlane& GetPrimaryPlane(const OverlayPlaneList& overlays) {
for (size_t i = 0; i < overlays.size(); ++i) {
if (overlays[i].z_order == 0)
return overlays[i];
}
NOTREACHED();
return overlays[0];
}
} // namespace } // namespace
OzoneOverlayPlane::OzoneOverlayPlane(ScanoutSurface* scanout, OverlayPlane::OverlayPlane(scoped_refptr<ScanoutBuffer> buffer)
int z_order, : buffer(buffer),
gfx::OverlayTransform plane_transform, z_order(0),
const gfx::Rect& display_bounds, display_bounds(gfx::Point(), buffer->GetSize()),
const gfx::RectF& crop_rect) crop_rect(0, 0, 1, 1),
: scanout(scanout), overlay_plane(0) {}
OverlayPlane::OverlayPlane(scoped_refptr<ScanoutBuffer> buffer,
int z_order,
gfx::OverlayTransform plane_transform,
const gfx::Rect& display_bounds,
const gfx::RectF& crop_rect)
: buffer(buffer),
z_order(z_order), z_order(z_order),
plane_transform(plane_transform), plane_transform(plane_transform),
display_bounds(display_bounds), display_bounds(display_bounds),
...@@ -60,6 +76,8 @@ OzoneOverlayPlane::OzoneOverlayPlane(ScanoutSurface* scanout, ...@@ -60,6 +76,8 @@ OzoneOverlayPlane::OzoneOverlayPlane(ScanoutSurface* scanout,
overlay_plane(0) { overlay_plane(0) {
} }
OverlayPlane::~OverlayPlane() {}
HardwareDisplayController::HardwareDisplayController( HardwareDisplayController::HardwareDisplayController(
DriWrapper* drm, DriWrapper* drm,
uint32_t connector_id, uint32_t connector_id,
...@@ -67,7 +85,6 @@ HardwareDisplayController::HardwareDisplayController( ...@@ -67,7 +85,6 @@ HardwareDisplayController::HardwareDisplayController(
: drm_(drm), : drm_(drm),
connector_id_(connector_id), connector_id_(connector_id),
crtc_id_(crtc_id), crtc_id_(crtc_id),
surface_(),
time_of_last_flip_(0), time_of_last_flip_(0),
is_disabled_(true), is_disabled_(true),
saved_crtc_(drm_->GetCrtc(crtc_id_)) {} saved_crtc_(drm_->GetCrtc(crtc_id_)) {}
...@@ -78,45 +95,35 @@ HardwareDisplayController::~HardwareDisplayController() { ...@@ -78,45 +95,35 @@ HardwareDisplayController::~HardwareDisplayController() {
// Reset the cursor. // Reset the cursor.
UnsetCursor(); UnsetCursor();
UnbindSurfaceFromController();
} }
bool bool HardwareDisplayController::Modeset(const OverlayPlane& primary,
HardwareDisplayController::BindSurfaceToController( drmModeModeInfo mode) {
scoped_ptr<ScanoutSurface> surface, drmModeModeInfo mode) { CHECK(primary.buffer);
CHECK(surface);
if (!drm_->SetCrtc(crtc_id_, if (!drm_->SetCrtc(crtc_id_,
surface->GetFramebufferId(), primary.buffer->GetFramebufferId(),
&connector_id_, &connector_id_,
&mode)) { &mode)) {
LOG(ERROR) << "Failed to modeset: error='" << strerror(errno) LOG(ERROR) << "Failed to modeset: error='" << strerror(errno)
<< "' crtc=" << crtc_id_ << " connector=" << connector_id_ << "' crtc=" << crtc_id_ << " connector=" << connector_id_
<< " framebuffer_id=" << surface->GetFramebufferId() << " framebuffer_id=" << primary.buffer->GetFramebufferId()
<< " mode=" << mode.hdisplay << "x" << mode.vdisplay << "@" << " mode=" << mode.hdisplay << "x" << mode.vdisplay << "@"
<< mode.vrefresh; << mode.vrefresh;
return false; return false;
} }
surface_.reset(surface.release()); current_planes_ = std::vector<OverlayPlane>(1, primary);
pending_planes_.clear();
mode_ = mode; mode_ = mode;
is_disabled_ = false; is_disabled_ = false;
return true; return true;
} }
void HardwareDisplayController::UnbindSurfaceFromController() {
drm_->SetCrtc(crtc_id_, 0, 0, NULL);
surface_.reset();
memset(&mode_, 0, sizeof(mode_));
is_disabled_ = true;
}
bool HardwareDisplayController::Enable() { bool HardwareDisplayController::Enable() {
CHECK(surface_); OverlayPlane primary = GetPrimaryPlane(current_planes_);
if (is_disabled_) { CHECK(primary.buffer);
scoped_ptr<ScanoutSurface> surface(surface_.release()); if (is_disabled_)
return BindSurfaceToController(surface.Pass(), mode_); return Modeset(primary, mode_);
}
return true; return true;
} }
...@@ -126,46 +133,29 @@ void HardwareDisplayController::Disable() { ...@@ -126,46 +133,29 @@ void HardwareDisplayController::Disable() {
is_disabled_ = true; is_disabled_ = true;
} }
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( bool HardwareDisplayController::SchedulePageFlip(
const std::vector<OzoneOverlayPlane>& overlays, const OverlayPlaneList& overlays) {
NativePixmapList* references) { CHECK_LE(1u, overlays.size());
ScanoutSurface* primary = GetPrimaryPlane(overlays); const OverlayPlane& primary = GetPrimaryPlane(overlays);
CHECK(primary); CHECK(primary.buffer);
primary->PreSwapBuffers();
if (!is_disabled_ && if (!is_disabled_ &&
!drm_->PageFlip(crtc_id_, primary->GetFramebufferId(), this)) { !drm_->PageFlip(crtc_id_, primary.buffer->GetFramebufferId(), this)) {
LOG(ERROR) << "Cannot page flip: " << strerror(errno); LOG(ERROR) << "Cannot page flip: " << strerror(errno);
return false; return false;
} }
current_overlay_references_.clear(); pending_planes_ = overlays;
if (references)
current_overlay_references_.swap(*references);
for (size_t i = 0; i < overlays.size(); i++) { for (size_t i = 0; i < overlays.size(); i++) {
const OzoneOverlayPlane& plane = overlays[i]; const OverlayPlane& plane = overlays[i];
if (!plane.overlay_plane) if (!plane.overlay_plane)
continue; continue;
const gfx::Size& size = plane.scanout->Size(); const gfx::Size& size = plane.buffer->GetSize();
gfx::RectF crop_rect = plane.crop_rect; gfx::RectF crop_rect = plane.crop_rect;
crop_rect.Scale(size.width(), size.height()); crop_rect.Scale(size.width(), size.height());
if (!drm_->PageFlipOverlay(crtc_id_, if (!drm_->PageFlipOverlay(crtc_id_,
plane.scanout->GetFramebufferId(), plane.buffer->GetFramebufferId(),
plane.display_bounds, plane.display_bounds,
crop_rect, crop_rect,
plane.overlay_plane)) { plane.overlay_plane)) {
...@@ -199,7 +189,8 @@ void HardwareDisplayController::OnPageFlipEvent(unsigned int frame, ...@@ -199,7 +189,8 @@ void HardwareDisplayController::OnPageFlipEvent(unsigned int frame,
static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond +
useconds; useconds;
surface_->SwapBuffers(); current_planes_ = pending_planes_;
pending_planes_.clear();
} }
bool HardwareDisplayController::SetCursor(scoped_refptr<ScanoutBuffer> buffer) { bool HardwareDisplayController::SetCursor(scoped_refptr<ScanoutBuffer> buffer) {
......
...@@ -21,20 +21,21 @@ class Point; ...@@ -21,20 +21,21 @@ class Point;
namespace ui { namespace ui {
class NativePixmap;
class ScanoutBuffer; class ScanoutBuffer;
class ScanoutSurface;
typedef std::vector<scoped_refptr<NativePixmap> > NativePixmapList; struct OverlayPlane {
// Simpler constructor for the primary plane.
explicit OverlayPlane(scoped_refptr<ScanoutBuffer> buffer);
struct OzoneOverlayPlane { OverlayPlane(scoped_refptr<ScanoutBuffer> buffer,
OzoneOverlayPlane(ScanoutSurface* scanout, int z_order,
int z_order, gfx::OverlayTransform plane_transform,
gfx::OverlayTransform plane_transform, const gfx::Rect& display_bounds,
const gfx::Rect& display_bounds, const gfx::RectF& crop_rect);
const gfx::RectF& crop_rect);
ScanoutSurface* scanout; ~OverlayPlane();
scoped_refptr<ScanoutBuffer> buffer;
int z_order; int z_order;
gfx::OverlayTransform plane_transform; gfx::OverlayTransform plane_transform;
gfx::Rect display_bounds; gfx::Rect display_bounds;
...@@ -42,6 +43,8 @@ struct OzoneOverlayPlane { ...@@ -42,6 +43,8 @@ struct OzoneOverlayPlane {
int overlay_plane; int overlay_plane;
}; };
typedef std::vector<OverlayPlane> OverlayPlaneList;
// The HDCOz will handle modesettings and scannout operations for hardware // The HDCOz will handle modesettings and scannout operations for hardware
// devices. // devices.
// //
...@@ -105,11 +108,10 @@ class HardwareDisplayController ...@@ -105,11 +108,10 @@ class HardwareDisplayController
~HardwareDisplayController(); ~HardwareDisplayController();
// Associate the HDCO with a surface implementation and initialize it. // Performs the initial CRTC configuration. If successful, it will display the
bool BindSurfaceToController(scoped_ptr<ScanoutSurface> surface, // framebuffer for |primary| with |mode|.
drmModeModeInfo mode); bool Modeset(const OverlayPlane& primary,
drmModeModeInfo mode);
void UnbindSurfaceFromController();
// Reconfigures the CRTC with the current surface and mode. // Reconfigures the CRTC with the current surface and mode.
bool Enable(); bool Enable();
...@@ -117,14 +119,14 @@ class HardwareDisplayController ...@@ -117,14 +119,14 @@ class HardwareDisplayController
// Disables the CRTC. // Disables the CRTC.
void Disable(); void Disable();
// Schedules the |surface_|'s framebuffer to be displayed on the next vsync // Schedules the |overlays|' framebuffers to be displayed on the next vsync
// event. The event will be posted on the graphics card file descriptor |fd_| // event. The event will be posted on the graphics card file descriptor |fd_|
// and it can be read and processed by |drmHandleEvent|. That function can // and it can be read and processed by |drmHandleEvent|. That function can
// define the callback for the page flip event. A generic data argument will // define the callback for the page flip event. A generic data argument will
// be presented to the callback. We use that argument to pass in the HDCO // be presented to the callback. We use that argument to pass in the HDCO
// object the event belongs to. // object the event belongs to.
// //
// Between this call and the callback, the framebuffer used in this call // Between this call and the callback, the framebuffers used in this call
// should not be modified in any way as it would cause screen tearing if the // should not be modified in any way as it would cause screen tearing if the
// hardware performed the flip. Note that the frontbuffer should also not // hardware performed the flip. Note that the frontbuffer should also not
// be modified as it could still be displayed. // be modified as it could still be displayed.
...@@ -133,8 +135,7 @@ class HardwareDisplayController ...@@ -133,8 +135,7 @@ class HardwareDisplayController
// called again before the page flip occurrs. // called again before the page flip occurrs.
// //
// Returns true if the page flip was successfully registered, false otherwise. // Returns true if the page flip was successfully registered, false otherwise.
bool SchedulePageFlip(const std::vector<OzoneOverlayPlane>& overlays, bool SchedulePageFlip(const OverlayPlaneList& overlays);
NativePixmapList* references);
// TODO(dnicoara) This should be on the MessageLoop when Ozone can have // TODO(dnicoara) This should be on the MessageLoop when Ozone can have
// BeginFrame can be triggered explicitly by Ozone. // BeginFrame can be triggered explicitly by Ozone.
...@@ -161,19 +162,14 @@ class HardwareDisplayController ...@@ -161,19 +162,14 @@ class HardwareDisplayController
const drmModeModeInfo& get_mode() const { return mode_; }; const drmModeModeInfo& get_mode() const { return mode_; };
uint32_t connector_id() const { return connector_id_; } uint32_t connector_id() const { return connector_id_; }
uint32_t crtc_id() const { return crtc_id_; } uint32_t crtc_id() const { return crtc_id_; }
ScanoutSurface* surface() const {
return surface_.get();
};
uint64_t get_time_of_last_flip() const { uint64_t get_time_of_last_flip() const {
return time_of_last_flip_; return time_of_last_flip_;
}; };
private: private:
ScanoutSurface* GetPrimaryPlane( OverlayPlaneList current_planes_;
const std::vector<OzoneOverlayPlane>& overlays); OverlayPlaneList pending_planes_;
NativePixmapList current_overlay_references_;
// Object containing the connection to the graphics device and wraps the API // Object containing the connection to the graphics device and wraps the API
// calls to control it. // calls to control it.
...@@ -186,8 +182,6 @@ class HardwareDisplayController ...@@ -186,8 +182,6 @@ class HardwareDisplayController
drmModeModeInfo mode_; drmModeModeInfo mode_;
scoped_ptr<ScanoutSurface> surface_;
scoped_refptr<ScanoutBuffer> cursor_buffer_; scoped_refptr<ScanoutBuffer> cursor_buffer_;
uint64_t time_of_last_flip_; uint64_t time_of_last_flip_;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/dri_surface.h"
#include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h"
...@@ -20,6 +19,23 @@ const drmModeModeInfo kDefaultMode = ...@@ -20,6 +19,23 @@ const drmModeModeInfo kDefaultMode =
const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay); const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay);
const gfx::SizeF kDefaultModeSizeF(1.0, 1.0); const gfx::SizeF kDefaultModeSizeF(1.0, 1.0);
class MockScanoutBuffer : public ui::ScanoutBuffer {
public:
MockScanoutBuffer(const gfx::Size& size) : size_(size) {}
// ScanoutBuffer:
virtual uint32_t GetFramebufferId() const OVERRIDE {return 0; }
virtual uint32_t GetHandle() const OVERRIDE { return 0; }
virtual gfx::Size GetSize() const OVERRIDE { return size_; }
private:
virtual ~MockScanoutBuffer() {}
gfx::Size size_;
DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer);
};
} // namespace } // namespace
class HardwareDisplayControllerTest : public testing::Test { class HardwareDisplayControllerTest : public testing::Test {
...@@ -47,122 +63,97 @@ void HardwareDisplayControllerTest::TearDown() { ...@@ -47,122 +63,97 @@ void HardwareDisplayControllerTest::TearDown() {
drm_.reset(); drm_.reset();
} }
TEST_F(HardwareDisplayControllerTest, CheckStateAfterSurfaceIsBound) { TEST_F(HardwareDisplayControllerTest, CheckModesettingResult) {
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); new MockScanoutBuffer(kDefaultModeSize)));
EXPECT_TRUE(surface->Initialize()); EXPECT_TRUE(controller_->Modeset(plane, kDefaultMode));
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), EXPECT_FALSE(plane.buffer->HasOneRef());
kDefaultMode));
EXPECT_TRUE(controller_->surface() != NULL);
} }
TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) { TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); new MockScanoutBuffer(kDefaultModeSize)));
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
EXPECT_TRUE(surface->Initialize()); ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>(
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), new MockScanoutBuffer(kDefaultModeSize)));
kDefaultMode));
EXPECT_TRUE(controller_->SchedulePageFlip( EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL)); std::vector<ui::OverlayPlane>(1, plane2)));
EXPECT_TRUE(controller_->surface() != NULL); controller_->WaitForPageFlipEvent();
EXPECT_TRUE(plane1.buffer->HasOneRef());
EXPECT_FALSE(plane2.buffer->HasOneRef());
EXPECT_EQ(1, drm_->get_page_flip_call_count());
EXPECT_EQ(0, drm_->get_overlay_flip_call_count());
} }
TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) { TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) {
drm_->set_set_crtc_expectation(false); drm_->set_set_crtc_expectation(false);
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); kDefaultModeSize)));
EXPECT_TRUE(surface->Initialize()); EXPECT_FALSE(controller_->Modeset(plane, kDefaultMode));
EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass(), EXPECT_TRUE(plane.buffer->HasOneRef());
kDefaultMode));
EXPECT_EQ(NULL, controller_->surface());
} }
TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) { TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) {
drm_->set_page_flip_expectation(false); drm_->set_page_flip_expectation(false);
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); new MockScanoutBuffer(kDefaultModeSize)));
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
EXPECT_TRUE(surface->Initialize()); ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>(
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), new MockScanoutBuffer(kDefaultModeSize)));
kDefaultMode));
EXPECT_FALSE(controller_->SchedulePageFlip( EXPECT_FALSE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL)); std::vector<ui::OverlayPlane>(1, plane2)));
EXPECT_FALSE(plane1.buffer->HasOneRef());
EXPECT_TRUE(plane2.buffer->HasOneRef());
} }
TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) { TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) {
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); new MockScanoutBuffer(kDefaultModeSize)));
EXPECT_TRUE(surface->Initialize()); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
controller_->Disable(); controller_->Disable();
ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>(
new MockScanoutBuffer(kDefaultModeSize)));
EXPECT_TRUE(controller_->SchedulePageFlip( EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL)); std::vector<ui::OverlayPlane>(1, plane2)));
controller_->WaitForPageFlipEvent();
EXPECT_EQ(0, drm_->get_page_flip_call_count()); EXPECT_EQ(0, drm_->get_page_flip_call_count());
surface.reset(new ui::DriSurface(drm_.get(), kDefaultModeSize)); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
EXPECT_TRUE(surface->Initialize());
EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
kDefaultMode));
EXPECT_TRUE(controller_->SchedulePageFlip( EXPECT_TRUE(controller_->SchedulePageFlip(
std::vector<ui::OzoneOverlayPlane>(), NULL)); std::vector<ui::OverlayPlane>(1, plane2)));
controller_->WaitForPageFlipEvent();
EXPECT_EQ(1, drm_->get_page_flip_call_count()); EXPECT_EQ(1, drm_->get_page_flip_call_count());
} }
TEST_F(HardwareDisplayControllerTest, CheckOverlayMainSurfaceReplacement) {
scoped_ptr<ui::ScanoutSurface> surface(
new ui::DriSurface(drm_.get(), kDefaultModeSize));
scoped_ptr<ui::ScanoutSurface> overlay(
new ui::DriSurface(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) { TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) {
scoped_ptr<ui::ScanoutSurface> surface( ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); new MockScanoutBuffer(kDefaultModeSize)));
scoped_ptr<ui::ScanoutSurface> overlay( ui::OverlayPlane plane2(
new ui::DriSurface(drm_.get(), kDefaultModeSize)); scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(kDefaultModeSize)),
1,
EXPECT_TRUE(surface->Initialize()); gfx::OVERLAY_TRANSFORM_NONE,
EXPECT_TRUE( gfx::Rect(kDefaultModeSize),
controller_->BindSurfaceToController(surface.Pass(), kDefaultMode)); gfx::RectF(kDefaultModeSizeF));
EXPECT_TRUE(overlay->Initialize()); plane2.overlay_plane = 1; // Force association with a plane.
std::vector<ui::OzoneOverlayPlane> overlays; EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
std::vector<scoped_refptr<ui::NativePixmap> > overlay_refs;
std::vector<ui::OverlayPlane> overlays;
overlays.push_back(ui::OzoneOverlayPlane(overlay.get(), overlays.push_back(plane1);
1, overlays.push_back(plane2);
gfx::OVERLAY_TRANSFORM_NONE,
gfx::Rect(kDefaultModeSize), EXPECT_TRUE(controller_->SchedulePageFlip(overlays));
gfx::RectF(kDefaultModeSizeF))); controller_->WaitForPageFlipEvent();
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_page_flip_call_count());
EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); EXPECT_EQ(1, drm_->get_overlay_flip_call_count());
} }
...@@ -10,10 +10,9 @@ ...@@ -10,10 +10,9 @@
#include "ui/events/ozone/evdev/event_factory_evdev.h" #include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/ozone/common/window/platform_window_compat.h" #include "ui/ozone/common/window/platform_window_compat.h"
#include "ui/ozone/platform/dri/cursor_factory_evdev_dri.h" #include "ui/ozone/platform/dri/cursor_factory_evdev_dri.h"
#include "ui/ozone/platform/dri/dri_surface.h" #include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/dri_surface_factory.h" #include "ui/ozone/platform/dri/dri_surface_factory.h"
#include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/platform/dri/scanout_surface.h"
#include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/platform/dri/virtual_terminal_manager.h" #include "ui/ozone/platform/dri/virtual_terminal_manager.h"
#include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/ozone_platform.h"
...@@ -29,21 +28,6 @@ namespace { ...@@ -29,21 +28,6 @@ namespace {
const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; const char kDefaultGraphicsCardPath[] = "/dev/dri/card0";
class DriSurfaceGenerator : public ScanoutSurfaceGenerator {
public:
DriSurfaceGenerator(DriWrapper* dri) : dri_(dri) {}
virtual ~DriSurfaceGenerator() {}
virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE {
return new DriSurface(dri_, size);
}
private:
DriWrapper* dri_; // Not owned.
DISALLOW_COPY_AND_ASSIGN(DriSurfaceGenerator);
};
// OzonePlatform for Linux DRI (Direct Rendering Infrastructure) // OzonePlatform for Linux DRI (Direct Rendering Infrastructure)
// //
// This platform is Linux without any display server (no X, wayland, or // This platform is Linux without any display server (no X, wayland, or
...@@ -53,9 +37,9 @@ class OzonePlatformDri : public OzonePlatform { ...@@ -53,9 +37,9 @@ class OzonePlatformDri : public OzonePlatform {
OzonePlatformDri() OzonePlatformDri()
: vt_manager_(new VirtualTerminalManager()), : vt_manager_(new VirtualTerminalManager()),
dri_(new DriWrapper(kDefaultGraphicsCardPath)), dri_(new DriWrapper(kDefaultGraphicsCardPath)),
surface_generator_(new DriSurfaceGenerator(dri_.get())), buffer_generator_(new DriBufferGenerator(dri_.get())),
screen_manager_(new ScreenManager(dri_.get(), screen_manager_(new ScreenManager(dri_.get(),
surface_generator_.get())), buffer_generator_.get())),
device_manager_(CreateDeviceManager()) { device_manager_(CreateDeviceManager()) {
base::AtExitManager::RegisterTask( base::AtExitManager::RegisterTask(
base::Bind(&base::DeletePointer<OzonePlatformDri>, this)); base::Bind(&base::DeletePointer<OzonePlatformDri>, this));
...@@ -110,7 +94,7 @@ class OzonePlatformDri : public OzonePlatform { ...@@ -110,7 +94,7 @@ class OzonePlatformDri : public OzonePlatform {
private: private:
scoped_ptr<VirtualTerminalManager> vt_manager_; scoped_ptr<VirtualTerminalManager> vt_manager_;
scoped_ptr<DriWrapper> dri_; scoped_ptr<DriWrapper> dri_;
scoped_ptr<DriSurfaceGenerator> surface_generator_; scoped_ptr<DriBufferGenerator> buffer_generator_;
scoped_ptr<ScreenManager> screen_manager_; scoped_ptr<ScreenManager> screen_manager_;
scoped_ptr<DeviceManager> device_manager_; scoped_ptr<DeviceManager> device_manager_;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "ui/ozone/platform/dri/gbm_surface_factory.h" #include "ui/ozone/platform/dri/gbm_surface_factory.h"
#include "ui/ozone/platform/dri/gpu_platform_support_gbm.h" #include "ui/ozone/platform/dri/gpu_platform_support_gbm.h"
#include "ui/ozone/platform/dri/gpu_platform_support_host_gbm.h" #include "ui/ozone/platform/dri/gpu_platform_support_host_gbm.h"
#include "ui/ozone/platform/dri/scanout_surface.h" #include "ui/ozone/platform/dri/scanout_buffer.h"
#include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/platform/dri/virtual_terminal_manager.h" #include "ui/ozone/platform/dri/virtual_terminal_manager.h"
#include "ui/ozone/public/cursor_factory_ozone.h" #include "ui/ozone/public/cursor_factory_ozone.h"
...@@ -40,13 +40,13 @@ namespace { ...@@ -40,13 +40,13 @@ namespace {
const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; const char kDefaultGraphicsCardPath[] = "/dev/dri/card0";
class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { class GbmBufferGenerator : public ScanoutBufferGenerator {
public: public:
GbmSurfaceGenerator(DriWrapper* dri) GbmBufferGenerator(DriWrapper* dri)
: dri_(dri), : dri_(dri),
glapi_lib_(dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL)), glapi_lib_(dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL)),
device_(gbm_create_device(dri_->get_fd())) {} device_(gbm_create_device(dri_->get_fd())) {}
virtual ~GbmSurfaceGenerator() { virtual ~GbmBufferGenerator() {
gbm_device_destroy(device_); gbm_device_destroy(device_);
if (glapi_lib_) if (glapi_lib_)
dlclose(glapi_lib_); dlclose(glapi_lib_);
...@@ -54,8 +54,9 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { ...@@ -54,8 +54,9 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator {
gbm_device* device() const { return device_; } gbm_device* device() const { return device_; }
virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE { virtual scoped_refptr<ScanoutBuffer> Create(const gfx::Size& size) OVERRIDE {
return new GbmSurface(device_, dri_, size); return GbmBuffer::CreateBuffer(
dri_, device_, SurfaceFactoryOzone::RGBA_8888, size, true);
} }
protected: protected:
...@@ -66,22 +67,7 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { ...@@ -66,22 +67,7 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator {
gbm_device* device_; gbm_device* device_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceGenerator); DISALLOW_COPY_AND_ASSIGN(GbmBufferGenerator);
};
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 { class OzonePlatformGbm : public OzonePlatform {
...@@ -142,17 +128,14 @@ class OzonePlatformGbm : public OzonePlatform { ...@@ -142,17 +128,14 @@ class OzonePlatformGbm : public OzonePlatform {
virtual void InitializeGPU() OVERRIDE { virtual void InitializeGPU() OVERRIDE {
dri_.reset(new DriWrapper(kDefaultGraphicsCardPath)); dri_.reset(new DriWrapper(kDefaultGraphicsCardPath));
if (use_surfaceless_) buffer_generator_.reset(new GbmBufferGenerator(dri_.get()));
surface_generator_.reset(new GbmEglImageSurfaceGenerator(dri_.get()));
else
surface_generator_.reset(new GbmSurfaceGenerator(dri_.get()));
screen_manager_.reset(new ScreenManager(dri_.get(), screen_manager_.reset(new ScreenManager(dri_.get(),
surface_generator_.get())); buffer_generator_.get()));
if (!surface_factory_ozone_) if (!surface_factory_ozone_)
surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_)); surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_));
surface_factory_ozone_->InitializeGpu(dri_.get(), surface_factory_ozone_->InitializeGpu(dri_.get(),
surface_generator_->device(), buffer_generator_->device(),
screen_manager_.get()); screen_manager_.get());
gpu_platform_support_.reset( gpu_platform_support_.reset(
...@@ -171,7 +154,7 @@ class OzonePlatformGbm : public OzonePlatform { ...@@ -171,7 +154,7 @@ class OzonePlatformGbm : public OzonePlatform {
bool use_surfaceless_; bool use_surfaceless_;
scoped_ptr<VirtualTerminalManager> vt_manager_; scoped_ptr<VirtualTerminalManager> vt_manager_;
scoped_ptr<DriWrapper> dri_; scoped_ptr<DriWrapper> dri_;
scoped_ptr<GbmSurfaceGenerator> surface_generator_; scoped_ptr<GbmBufferGenerator> buffer_generator_;
scoped_ptr<ScreenManager> screen_manager_; scoped_ptr<ScreenManager> screen_manager_;
scoped_ptr<DeviceManager> device_manager_; scoped_ptr<DeviceManager> device_manager_;
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/dri/dri_util.h" #include "ui/ozone/platform/dri/dri_util.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/scanout_surface.h" #include "ui/ozone/platform/dri/scanout_buffer.h"
namespace ui { namespace ui {
ScreenManager::ScreenManager( ScreenManager::ScreenManager(
DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator) DriWrapper* dri, ScanoutBufferGenerator* buffer_generator)
: dri_(dri), surface_generator_(surface_generator), last_added_widget_(0) { : dri_(dri), buffer_generator_(buffer_generator), last_added_widget_(0) {
} }
ScreenManager::~ScreenManager() { ScreenManager::~ScreenManager() {
...@@ -45,7 +45,6 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc, ...@@ -45,7 +45,6 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
return it->second->Enable(); return it->second->Enable();
controller = it->second; controller = it->second;
controller->UnbindSurfaceFromController();
} }
if (it == controllers_.end()) { if (it == controllers_.end()) {
...@@ -54,19 +53,16 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc, ...@@ -54,19 +53,16 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
} }
// Create a surface suitable for the current controller. // Create a surface suitable for the current controller.
scoped_ptr<ScanoutSurface> surface( scoped_refptr<ScanoutBuffer> buffer =
surface_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay))); buffer_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay));
if (!surface->Initialize()) { if (!buffer) {
LOG(ERROR) << "Failed to initialize surface"; LOG(ERROR) << "Failed to create scanout buffer";
return false; return false;
} }
// Bind the surface to the controller. This will register the backing buffers if (!controller->Modeset(OverlayPlane(buffer), mode)) {
// with the hardware CRTC such that we can show the buffers and performs the LOG(ERROR) << "Failed to modeset controller";
// initial modeset. The controller takes ownership of the surface.
if (!controller->BindSurfaceToController(surface.Pass(), mode)) {
LOG(ERROR) << "Failed to bind surface to controller";
return false; return false;
} }
......
...@@ -23,12 +23,12 @@ class Size; ...@@ -23,12 +23,12 @@ class Size;
namespace ui { namespace ui {
class DriWrapper; class DriWrapper;
class ScanoutSurfaceGenerator; class ScanoutBufferGenerator;
// Responsible for keeping track of active displays and configuring them. // Responsible for keeping track of active displays and configuring them.
class ScreenManager { class ScreenManager {
public: public:
ScreenManager(DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator); ScreenManager(DriWrapper* dri, ScanoutBufferGenerator* surface_generator);
virtual ~ScreenManager(); virtual ~ScreenManager();
// Remove a display controller from the list of active controllers. The // Remove a display controller from the list of active controllers. The
...@@ -70,7 +70,7 @@ class ScreenManager { ...@@ -70,7 +70,7 @@ class ScreenManager {
virtual void ForceInitializationOfPrimaryDisplay(); virtual void ForceInitializationOfPrimaryDisplay();
DriWrapper* dri_; // Not owned. DriWrapper* dri_; // Not owned.
ScanoutSurfaceGenerator* surface_generator_; // Not owned. ScanoutBufferGenerator* buffer_generator_; // Not owned.
// Mapping between an accelerated widget and an active display. // Mapping between an accelerated widget and an active display.
HardwareDisplayControllerMap controllers_; HardwareDisplayControllerMap controllers_;
gfx::AcceleratedWidget last_added_widget_; gfx::AcceleratedWidget last_added_widget_;
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/hardware_display_controller.h"
#include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h"
#include "ui/ozone/platform/dri/test/mock_surface_generator.h"
namespace { namespace {
...@@ -17,8 +17,8 @@ const drmModeModeInfo kDefaultMode = ...@@ -17,8 +17,8 @@ const drmModeModeInfo kDefaultMode =
class MockScreenManager : public ui::ScreenManager { class MockScreenManager : public ui::ScreenManager {
public: public:
MockScreenManager(ui::DriWrapper* dri, MockScreenManager(ui::DriWrapper* dri,
ui::ScanoutSurfaceGenerator* surface_generator) ui::ScanoutBufferGenerator* buffer_generator)
: ScreenManager(dri, surface_generator), dri_(dri) {} : ScreenManager(dri, buffer_generator), dri_(dri) {}
virtual void ForceInitializationOfPrimaryDisplay() OVERRIDE {} virtual void ForceInitializationOfPrimaryDisplay() OVERRIDE {}
...@@ -37,9 +37,9 @@ class ScreenManagerTest : public testing::Test { ...@@ -37,9 +37,9 @@ class ScreenManagerTest : public testing::Test {
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
dri_.reset(new ui::MockDriWrapper(3)); dri_.reset(new ui::MockDriWrapper(3));
surface_generator_.reset(new ui::MockSurfaceGenerator(dri_.get())); buffer_generator_.reset(new ui::DriBufferGenerator(dri_.get()));
screen_manager_.reset(new MockScreenManager( screen_manager_.reset(new MockScreenManager(
dri_.get(), surface_generator_.get())); dri_.get(), buffer_generator_.get()));
} }
virtual void TearDown() OVERRIDE { virtual void TearDown() OVERRIDE {
screen_manager_.reset(); screen_manager_.reset();
...@@ -48,7 +48,7 @@ class ScreenManagerTest : public testing::Test { ...@@ -48,7 +48,7 @@ class ScreenManagerTest : public testing::Test {
protected: protected:
scoped_ptr<ui::MockDriWrapper> dri_; scoped_ptr<ui::MockDriWrapper> dri_;
scoped_ptr<ui::MockSurfaceGenerator> surface_generator_; scoped_ptr<ui::DriBufferGenerator> buffer_generator_;
scoped_ptr<MockScreenManager> screen_manager_; scoped_ptr<MockScreenManager> screen_manager_;
private: private:
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "ui/ozone/platform/dri/dri_surface.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/hardware_display_controller.h"
namespace ui { namespace ui {
...@@ -32,7 +31,9 @@ MockDriWrapper::MockDriWrapper(int fd) ...@@ -32,7 +31,9 @@ MockDriWrapper::MockDriWrapper(int fd)
set_crtc_expectation_(true), set_crtc_expectation_(true),
add_framebuffer_expectation_(true), add_framebuffer_expectation_(true),
page_flip_expectation_(true), page_flip_expectation_(true),
create_dumb_buffer_expectation_(true) { create_dumb_buffer_expectation_(true),
current_framebuffer_(0),
controller_(NULL) {
fd_ = fd; fd_ = fd;
} }
...@@ -49,6 +50,7 @@ bool MockDriWrapper::SetCrtc(uint32_t crtc_id, ...@@ -49,6 +50,7 @@ bool MockDriWrapper::SetCrtc(uint32_t crtc_id,
uint32_t framebuffer, uint32_t framebuffer,
uint32_t* connectors, uint32_t* connectors,
drmModeModeInfo* mode) { drmModeModeInfo* mode) {
current_framebuffer_ = framebuffer;
return set_crtc_expectation_; return set_crtc_expectation_;
} }
...@@ -78,7 +80,8 @@ bool MockDriWrapper::PageFlip(uint32_t crtc_id, ...@@ -78,7 +80,8 @@ bool MockDriWrapper::PageFlip(uint32_t crtc_id,
uint32_t framebuffer, uint32_t framebuffer,
void* data) { void* data) {
page_flip_call_count_++; page_flip_call_count_++;
static_cast<ui::HardwareDisplayController*>(data)->surface()->SwapBuffers(); current_framebuffer_ = framebuffer;
controller_ = static_cast<ui::HardwareDisplayController*>(data);
return page_flip_expectation_; return page_flip_expectation_;
} }
...@@ -119,6 +122,8 @@ bool MockDriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { ...@@ -119,6 +122,8 @@ bool MockDriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) {
} }
void MockDriWrapper::HandleEvent(drmEventContext& event) { void MockDriWrapper::HandleEvent(drmEventContext& event) {
if (controller_)
controller_->OnPageFlipEvent(0, 0, 0);
} }
bool MockDriWrapper::CreateDumbBuffer(const SkImageInfo& info, bool MockDriWrapper::CreateDumbBuffer(const SkImageInfo& info,
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
namespace ui { namespace ui {
class HardwareDisplayController;
// The real DriWrapper makes actual DRM calls which we can't use in unit tests. // The real DriWrapper makes actual DRM calls which we can't use in unit tests.
class MockDriWrapper : public ui::DriWrapper { class MockDriWrapper : public ui::DriWrapper {
public: public:
...@@ -39,6 +41,8 @@ class MockDriWrapper : public ui::DriWrapper { ...@@ -39,6 +41,8 @@ class MockDriWrapper : public ui::DriWrapper {
create_dumb_buffer_expectation_ = state; create_dumb_buffer_expectation_ = state;
} }
uint32_t current_framebuffer() const { return current_framebuffer_; }
const std::vector<skia::RefPtr<SkSurface> > buffers() const { const std::vector<skia::RefPtr<SkSurface> > buffers() const {
return buffers_; return buffers_;
} }
...@@ -100,8 +104,12 @@ class MockDriWrapper : public ui::DriWrapper { ...@@ -100,8 +104,12 @@ class MockDriWrapper : public ui::DriWrapper {
bool page_flip_expectation_; bool page_flip_expectation_;
bool create_dumb_buffer_expectation_; bool create_dumb_buffer_expectation_;
uint32_t current_framebuffer_;
std::vector<skia::RefPtr<SkSurface> > buffers_; std::vector<skia::RefPtr<SkSurface> > buffers_;
HardwareDisplayController* controller_;
DISALLOW_COPY_AND_ASSIGN(MockDriWrapper); DISALLOW_COPY_AND_ASSIGN(MockDriWrapper);
}; };
......
// 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 "ui/ozone/platform/dri/test/mock_surface_generator.h"
namespace ui {
MockSurfaceGenerator::MockSurfaceGenerator(DriWrapper* dri) : dri_(dri) {}
MockSurfaceGenerator::~MockSurfaceGenerator() {}
ScanoutSurface* MockSurfaceGenerator::Create(const gfx::Size& size) {
surfaces_.push_back(new DriSurface(dri_, size));
return surfaces_.back();
}
} // namespace ui
// 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 UI_OZONE_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_
#define UI_OZONE_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_
#include <vector>
#include "ui/ozone/platform/dri/dri_surface.h"
namespace gfx {
class Size;
}
namespace ui {
class DriWrapper;
class MockSurfaceGenerator : public ScanoutSurfaceGenerator {
public:
MockSurfaceGenerator(DriWrapper* dri);
virtual ~MockSurfaceGenerator();
std::vector<DriSurface*> surfaces() const { return surfaces_; }
// ScanoutSurfaceGenerator:
virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE;
private:
DriWrapper* dri_; // Not owned.
std::vector<DriSurface*> surfaces_;
DISALLOW_COPY_AND_ASSIGN(MockSurfaceGenerator);
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_
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