Skip to content

Instantly share code, notes, and snippets.

@tiagovignatti
Created October 22, 2014 20:16
Show Gist options
  • Save tiagovignatti/afe88984d2a03b2cafc0 to your computer and use it in GitHub Desktop.
Save tiagovignatti/afe88984d2a03b2cafc0 to your computer and use it in GitHub Desktop.
ozone-gbm: Workaround flip not able to change stride bug
diff --git a/ui/ozone/platform/dri/buffer_data.cc b/ui/ozone/platform/dri/buffer_data.cc
index a2ea1b3..3462fd0 100644
--- a/ui/ozone/platform/dri/buffer_data.cc
+++ b/ui/ozone/platform/dri/buffer_data.cc
@@ -20,6 +20,7 @@ const uint8_t kPixelDepth = 32;
BufferData::BufferData(DriWrapper* dri, gbm_bo* buffer)
: dri_(dri),
handle_(gbm_bo_get_handle(buffer).u32),
+ stride_(gbm_bo_get_stride(buffer)),
framebuffer_(0) {
// Register the buffer with the controller. This will allow us to scan out the
// buffer once we're done drawing into it. If we can't register the buffer
diff --git a/ui/ozone/platform/dri/buffer_data.h b/ui/ozone/platform/dri/buffer_data.h
index 2f3422d..0578d3c 100644
--- a/ui/ozone/platform/dri/buffer_data.h
+++ b/ui/ozone/platform/dri/buffer_data.h
@@ -32,6 +32,7 @@ class BufferData {
uint32_t framebuffer() const { return framebuffer_; }
uint32_t handle() const { return handle_; }
+ uint32_t stride() const { return stride_; }
private:
BufferData(DriWrapper* dri, gbm_bo* buffer);
@@ -41,6 +42,8 @@ class BufferData {
uint32_t handle_;
+ uint32_t stride_;
+
// ID provided by the controller when the buffer is registered. This ID is
// used when scanning out the buffer.
uint32_t framebuffer_;
diff --git a/ui/ozone/platform/dri/dri_surface.cc b/ui/ozone/platform/dri/dri_surface.cc
index e0813b6..ed4a720 100644
--- a/ui/ozone/platform/dri/dri_surface.cc
+++ b/ui/ozone/platform/dri/dri_surface.cc
@@ -54,6 +54,11 @@ uint32_t DriSurface::GetHandle() const {
return backbuffer()->handle();
}
+uint32_t DriSurface::GetStride() const {
+ CHECK(backbuffer());
+ return backbuffer()->stride();
+}
+
// 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() {
diff --git a/ui/ozone/platform/dri/dri_surface.h b/ui/ozone/platform/dri/dri_surface.h
index 9aa59b7..3749394 100644
--- a/ui/ozone/platform/dri/dri_surface.h
+++ b/ui/ozone/platform/dri/dri_surface.h
@@ -34,6 +34,7 @@ class DriSurface : public ScanoutSurface {
virtual uint32_t GetHandle() const OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
virtual gfx::Size Size() const OVERRIDE;
+ virtual uint32_t GetStride() const OVERRIDE;
private:
DriBuffer* frontbuffer() const { return bitmaps_[front_buffer_].get(); }
diff --git a/ui/ozone/platform/dri/gbm_surface.cc b/ui/ozone/platform/dri/gbm_surface.cc
index 99f0ae7..0aefa75 100644
--- a/ui/ozone/platform/dri/gbm_surface.cc
+++ b/ui/ozone/platform/dri/gbm_surface.cc
@@ -81,6 +81,16 @@ gfx::Size GbmSurface::Size() const {
return size_;
}
+uint32_t GbmSurface::GetStride() const {
+ if (!buffers_[front_buffer_ ^ 1])
+ return dumb_buffer_->stride();
+
+ BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]);
+ CHECK(data);
+
+ return data->stride();
+}
+
void GbmSurface::SwapBuffers() {
// If there was a frontbuffer, is no longer active. Release it back to GBM.
if (buffers_[front_buffer_])
diff --git a/ui/ozone/platform/dri/gbm_surface.h b/ui/ozone/platform/dri/gbm_surface.h
index 8a33ab5..ccf3ebb 100644
--- a/ui/ozone/platform/dri/gbm_surface.h
+++ b/ui/ozone/platform/dri/gbm_surface.h
@@ -33,6 +33,7 @@ class GbmSurface : public ScanoutSurface {
virtual uint32_t GetHandle() const OVERRIDE;
virtual gfx::Size Size() const OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
+ virtual uint32_t GetStride() const 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
diff --git a/ui/ozone/platform/dri/hardware_display_controller.cc b/ui/ozone/platform/dri/hardware_display_controller.cc
index 9e79118..e71a4d7 100644
--- a/ui/ozone/platform/dri/hardware_display_controller.cc
+++ b/ui/ozone/platform/dri/hardware_display_controller.cc
@@ -114,13 +114,23 @@ void HardwareDisplayController::Disable() {
bool HardwareDisplayController::SchedulePageFlip() {
CHECK(surface_);
- if (!is_disabled_ && !drm_->PageFlip(crtc_id_,
- surface_->GetFramebufferId(),
- this)) {
+ if (is_disabled_)
+ return true;
+
+ if (surface_->GetStride() != current_stride_ &&
+ !drm_->SetCrtc(crtc_id_, surface_->GetFramebufferId(),
+ &connector_id_, &mode_)) {
+ LOG(ERROR) << "Cannot mode set: " << strerror(errno);
+ return false;
+ }
+
+ if (!drm_->PageFlip(crtc_id_, surface_->GetFramebufferId(), this)) {
LOG(ERROR) << "Cannot page flip: " << strerror(errno);
return false;
}
+ current_stride_ = surface_->GetStride();
+
return true;
}
diff --git a/ui/ozone/platform/dri/hardware_display_controller.h b/ui/ozone/platform/dri/hardware_display_controller.h
index 472dbd6..fb9cd8f 100644
--- a/ui/ozone/platform/dri/hardware_display_controller.h
+++ b/ui/ozone/platform/dri/hardware_display_controller.h
@@ -173,6 +173,8 @@ class HardwareDisplayController
// once we no longer need it.
ScopedDrmCrtcPtr saved_crtc_;
+ uint32_t current_stride_;
+
DISALLOW_COPY_AND_ASSIGN(HardwareDisplayController);
};
diff --git a/ui/ozone/platform/dri/scanout_surface.h b/ui/ozone/platform/dri/scanout_surface.h
index d362ae1..267911f 100644
--- a/ui/ozone/platform/dri/scanout_surface.h
+++ b/ui/ozone/platform/dri/scanout_surface.h
@@ -70,6 +70,9 @@ class ScanoutSurface {
// Returns the surface size.
virtual gfx::Size Size() const = 0;
+
+ // Returns the stride of the current backbuffer.
+ virtual uint32_t GetStride() const = 0;
};
class ScanoutSurfaceGenerator {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment