| 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
|
|
|