Index: ui/ozone/platform/drm/gpu/crtc_controller.cc |
diff --git a/ui/ozone/platform/drm/gpu/crtc_controller.cc b/ui/ozone/platform/drm/gpu/crtc_controller.cc |
index ef49295dea71a8bccaa9cdd4da9dbf4fa5b3be6b..6c912c647290d0a3a271a81fb925f591c551db15 100644 |
--- a/ui/ozone/platform/drm/gpu/crtc_controller.cc |
+++ b/ui/ozone/platform/drm/gpu/crtc_controller.cc |
@@ -7,7 +7,7 @@ |
#include "base/logging.h" |
#include "base/time/time.h" |
#include "ui/ozone/platform/drm/gpu/drm_device.h" |
-#include "ui/ozone/platform/drm/gpu/page_flip_observer.h" |
+#include "ui/ozone/platform/drm/gpu/page_flip_request.h" |
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h" |
namespace ui { |
@@ -20,7 +20,6 @@ CrtcController::CrtcController(const scoped_refptr<DrmDevice>& drm, |
connector_(connector), |
saved_crtc_(drm->GetCrtc(crtc)), |
is_disabled_(true), |
- page_flip_pending_(false), |
time_of_last_flip_(0) { |
} |
@@ -28,6 +27,7 @@ CrtcController::~CrtcController() { |
if (!is_disabled_) { |
drm_->SetCrtc(saved_crtc_.get(), std::vector<uint32_t>(1, connector_)); |
SetCursor(nullptr); |
+ SignalPageFlipRequest(); |
} |
} |
@@ -51,7 +51,7 @@ bool CrtcController::Modeset(const OverlayPlane& plane, drmModeModeInfo mode) { |
// pending planes to the same values so that the callback keeps the correct |
// state. |
current_planes_ = std::vector<OverlayPlane>(1, plane); |
- if (page_flip_pending_) |
+ if (page_flip_request_.get()) |
pending_planes_ = current_planes_; |
ResetCursor(); |
@@ -67,14 +67,16 @@ bool CrtcController::Disable() { |
return drm_->DisableCrtc(crtc_); |
} |
-bool CrtcController::SchedulePageFlip(HardwareDisplayPlaneList* plane_list, |
- const OverlayPlaneList& overlays) { |
- DCHECK(!page_flip_pending_); |
+bool CrtcController::SchedulePageFlip( |
+ HardwareDisplayPlaneList* plane_list, |
+ const OverlayPlaneList& overlays, |
+ scoped_refptr<PageFlipRequest> page_flip_request) { |
+ DCHECK(!page_flip_request_.get()); |
DCHECK(!is_disabled_); |
const OverlayPlane* primary = OverlayPlane::GetPrimaryPlane(overlays); |
if (!primary) { |
LOG(ERROR) << "No primary plane to display on crtc " << crtc_; |
- FOR_EACH_OBSERVER(PageFlipObserver, observers_, OnPageFlipEvent()); |
+ page_flip_request->Signal(); |
return true; |
} |
DCHECK(primary->buffer.get()); |
@@ -84,31 +86,31 @@ bool CrtcController::SchedulePageFlip(HardwareDisplayPlaneList* plane_list, |
<< mode_.hdisplay << "x" << mode_.vdisplay << " got " |
<< primary->buffer->GetSize().ToString() << " for" |
<< " crtc=" << crtc_ << " connector=" << connector_; |
- FOR_EACH_OBSERVER(PageFlipObserver, observers_, OnPageFlipEvent()); |
+ page_flip_request->Signal(); |
return true; |
} |
if (!drm_->plane_manager()->AssignOverlayPlanes(plane_list, overlays, crtc_, |
this)) { |
PLOG(ERROR) << "Failed to assign overlay planes for crtc " << crtc_; |
+ page_flip_request->Signal(); |
return false; |
} |
- page_flip_pending_ = true; |
pending_planes_ = overlays; |
+ page_flip_request_ = page_flip_request; |
return true; |
} |
void CrtcController::PageFlipFailed() { |
pending_planes_.clear(); |
- page_flip_pending_ = false; |
+ SignalPageFlipRequest(); |
} |
void CrtcController::OnPageFlipEvent(unsigned int frame, |
unsigned int seconds, |
unsigned int useconds) { |
- page_flip_pending_ = false; |
time_of_last_flip_ = |
static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + |
useconds; |
@@ -116,7 +118,7 @@ void CrtcController::OnPageFlipEvent(unsigned int frame, |
current_planes_.clear(); |
current_planes_.swap(pending_planes_); |
- FOR_EACH_OBSERVER(PageFlipObserver, observers_, OnPageFlipEvent()); |
+ SignalPageFlipRequest(); |
} |
bool CrtcController::SetCursor(const scoped_refptr<ScanoutBuffer>& buffer) { |
@@ -131,14 +133,6 @@ bool CrtcController::MoveCursor(const gfx::Point& location) { |
return drm_->MoveCursor(crtc_, location); |
} |
-void CrtcController::AddObserver(PageFlipObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void CrtcController::RemoveObserver(PageFlipObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
bool CrtcController::ResetCursor() { |
uint32_t handle = 0; |
gfx::Size size; |
@@ -158,4 +152,16 @@ bool CrtcController::ResetCursor() { |
return status; |
} |
+void CrtcController::SignalPageFlipRequest() { |
+ if (page_flip_request_.get()) { |
+ // If another frame is queued up and available immediately, calling Signal() |
+ // may result in a call to SchedulePageFlip(), which will override |
+ // page_flip_request_ and possibly release the ref. Stash previous request |
+ // locally to avoid deleting the object we are making a call on. |
+ scoped_refptr<PageFlipRequest> last_request; |
+ last_request.swap(page_flip_request_); |
+ last_request->Signal(); |
+ } |
+} |
+ |
} // namespace ui |