From patchwork Tue Nov 4 22:09:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 5231131 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1657F9F295 for ; Tue, 4 Nov 2014 22:09:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0AE172017A for ; Tue, 4 Nov 2014 22:09:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id EE6BC20155 for ; Tue, 4 Nov 2014 22:09:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 07BFD6E59F; Tue, 4 Nov 2014 14:09:24 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wi0-f181.google.com (mail-wi0-f181.google.com [209.85.212.181]) by gabe.freedesktop.org (Postfix) with ESMTP id CCF866E59F for ; Tue, 4 Nov 2014 14:09:22 -0800 (PST) Received: by mail-wi0-f181.google.com with SMTP id n3so391203wiv.2 for ; Tue, 04 Nov 2014 14:09:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=28kei1RiOs/JrnbdUr6i16yy6w1uyS7H0/G1ASNbySQ=; b=XlNcHrXaQMiL4j2T3DaUj7G7EX56l4V1BJjeW8dghgRb4QbLAryUi3Av21DnUTMEDU HKcCFD1UjVSBWCyKmhDZre2GMh+pTof2m63VMFvBB1zKkaZtm5mXPn3zmIEzrj6GKARD 3RQvLYxgmM9FosgsxJref/LLkkiyznP2NRlsg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=28kei1RiOs/JrnbdUr6i16yy6w1uyS7H0/G1ASNbySQ=; b=PSzlQd33h9Nq1JrWRPzmko2ojJlmeHRmoOUu5uIXiTT7u+CQliFeNlVrejQ5vGMjb1 xOrEM2+m1P7ceva1IZFQIxG0arfUPLkPSp7M3Lx3RDd0+20EGIvZ67WEEepwFe3FSifE /rzSw4RssYCPxOKroCchzysxco0rVKfaE+lh1JQc0jCrV07HnsbhjMJmLA/L91ceACbG oF0aMZ5wsxeaWeXxW6MLocKp7r56uOhLNwWvobpGVJ4UzE83JDYi2J3WB7TaNKnYDluZ HSER7RiQyCVwOplEtAeiLWB5Jw5I7noYsA5Yillx02ZJTFNgW5txjHW2UzVYJ0PrJaf7 aURQ== X-Gm-Message-State: ALoCoQnOP1Awe70aVCvTzNFfn1YuxUWeCA1XbUspS3e1XZkvxMdaeOZwqCQN+GzFkHczdCMAk0oN X-Received: by 10.194.110.161 with SMTP id ib1mr31866658wjb.78.1415138961855; Tue, 04 Nov 2014 14:09:21 -0800 (PST) Received: from phenom.ffwll.local (84-73-67-144.dclient.hispeed.ch. [84.73.67.144]) by mx.google.com with ESMTPSA id gy4sm2451797wib.11.2014.11.04.14.09.19 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 04 Nov 2014 14:09:20 -0800 (PST) From: Daniel Vetter To: DRI Development Subject: [PATCH] drm/atomic-helper: implement ->page_flip Date: Tue, 4 Nov 2014 23:09:32 +0100 Message-Id: <1415138972-13178-1-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1414934370-11924-15-git-send-email-daniel.vetter@ffwll.ch> References: <1414934370-11924-15-git-send-email-daniel.vetter@ffwll.ch> Cc: Daniel Vetter , Intel Graphics Development X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently there is no way to implement async flips using atomic, that essentially requires us to be able to cancel pending requests mid-flight. To be able to do that (and I guess we want this since vblank synced updates whic opportunistically cancel still pending updates seem to be wanted) we'd need to add a mandatory cancellation mode. Depending upon the exact semantics we decide upon that could mean that userspace will not get completion events, or will get them all stacked up. So reject async updates for now. Also async updates usually means not vblank synced at all, and I guess for drivers which want to support this they should simply add a special pageflip handler (since usually you need a special flip cmd to achieve this). That kind of async flip is pretty much exclusively just used for games and benchmarks where dropping just one frame means you'll get a headshot or something bad like that ... And so slight amounts of tearing is acceptable. v2: Fixup kerneldoc, reported by Paulo. v3: Use the set_crtc_for_plane function to assign the crtc, since otherwise the book-keeping is off. v4: Update crtc->primary->fb since ->page_flip is the only driver callback where the core won't do this itself. We might want to fix this inconsistency eventually. v5: Use set_crtc_for_connector as suggested by Sean. Cc: Sean Paul Cc: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 92 +++++++++++++++++++++++++++++++++++++ include/drm/drm_atomic_helper.h | 5 ++ 2 files changed, 97 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 790edc18b2cb..36ccc42d43db 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1633,3 +1633,95 @@ backoff: goto retry; } EXPORT_SYMBOL(drm_atomic_helper_connector_set_property); + +/** + * drm_atomic_helper_page_flip - execute a legacy page flip + * @crtc: DRM crtc + * @fb: DRM framebuffer + * @event: optional DRM event to signal upon completion + * @flags: flip flags for non-vblank sync'ed updates + * + * Provides a default page flip implementation using the atomic driver interface. + * + * Note that for now so called async page flips (i.e. updates which are not + * synchronized to vblank) are not supported, since the atomic interfaces have + * no provisions for this yet. + * + * Returns: + * Returns 0 on success, negative errno numbers on failure. + */ +int drm_atomic_helper_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags) +{ + struct drm_plane *plane = crtc->primary; + struct drm_atomic_state *state; + struct drm_plane_state *plane_state; + struct drm_crtc_state *crtc_state; + int ret = 0; + + if (flags & DRM_MODE_PAGE_FLIP_ASYNC) + return -EINVAL; + + state = drm_atomic_state_alloc(plane->dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); +retry: + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + if (ret == -EDEADLK) + goto backoff; + else + goto fail; + } + crtc_state->event = event; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); + if (ret == -EDEADLK) + goto backoff; + else + goto fail; + } + + ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); + if (ret == -EDEADLK) + goto backoff; + plane_state->fb = fb; + + ret = drm_atomic_async_commit(state); + if (ret == -EDEADLK) + goto backoff; + + /* Driver takes ownership of state on successful async commit. */ + if (ret == 0) { + /* TODO: ->page_flip is the only driver callback where the core + * doesn't update plane->fb. For now patch it up here. */ + plane->fb = plane->state->fb; + + return 0; + } + +fail: + drm_atomic_state_free(state); + + return ret; +backoff: + drm_atomic_legacy_backoff(state); + drm_atomic_state_clear(state); + + /* + * Someone might have exchanged the framebuffer while we dropped locks + * in the backoff code. We need to fix up the fb refcount tracking the + * core does for us. + */ + plane->old_fb = plane->fb; + + goto retry; +} +EXPORT_SYMBOL(drm_atomic_helper_page_flip); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 8cd6fe7a48e5..28a2f3a815fd 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -69,5 +69,10 @@ int drm_atomic_helper_plane_set_property(struct drm_plane *plane, int drm_atomic_helper_connector_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val); +int drm_atomic_helper_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags); + #endif /* DRM_ATOMIC_HELPER_H_ */