From patchwork Tue Aug 11 14:06:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 40683 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7BE7TeF022420 for ; Tue, 11 Aug 2009 14:07:29 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 981A39EFD0; Tue, 11 Aug 2009 07:07:29 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail.ffwll.ch (cable-static-49-187.intergga.ch [157.161.49.187]) by gabe.freedesktop.org (Postfix) with ESMTP id 8EC639EFC7 for ; Tue, 11 Aug 2009 07:07:20 -0700 (PDT) Received: by mail.ffwll.ch (Postfix, from userid 1000) id 808A120C22E; Wed, 12 Aug 2009 00:00:48 +0200 (CEST) X-Spam-ASN: X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on orange.ffwll.ch X-Spam-Level: X-Spam-Hammy: 0.000-+--struct, 0.000-+--signedoffby, 0.000-+--signed-off-by X-Spam-Status: No, score=-4.4 required=6.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Spammy: 0.998-1--newly Received: from biene (unknown [192.168.23.129]) by mail.ffwll.ch (Postfix) with ESMTP id C71E720C231; Wed, 12 Aug 2009 00:00:08 +0200 (CEST) Received: from daniel by biene with local (Exim 4.69) (envelope-from ) id 1Mas0C-0003ew-4D; Tue, 11 Aug 2009 16:07:00 +0200 From: Daniel Vetter To: intel-gfx@lists.freedesktop.org Date: Tue, 11 Aug 2009 16:06:47 +0200 Message-Id: <6946914c42ba2bb0f6f7b6d1351f33af53a145fd.1249999028.git.daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <361705901f128de9afac9b43d386abf0be87a5b3.1249999028.git.daniel.vetter@ffwll.ch> References: <0328734a90544a6cd72d9eaf64015db9d3462921.1249999028.git.daniel.vetter@ffwll.ch> <10614c7dd4ecbb1b4d3dd6a15b949cb389053f1f.1249999028.git.daniel.vetter@ffwll.ch> <891b387c6b31972a3e339508e57bd660b2991a17.1249999028.git.daniel.vetter@ffwll.ch> <2096013512e0099bfbb89439943c1b70cccabc92.1249999028.git.daniel.vetter@ffwll.ch> <8a3ddc0d78dcb40a14f8037b81cf202eaa40c301.1249999028.git.daniel.vetter@ffwll.ch> <3e0435569d2d7f58d58eb2f7c8a6952cc29b6934.1249999028.git.daniel.vetter@ffwll.ch> <52250eeaf73398c9c1f91ca7b2317f785f8eba56.1249999028.git.daniel.vetter@ffwll.ch> <3a4e39fa527e6f1bec9306a0c9d7b69b222532a6.1249999028.git.daniel.vetter@ffwll.ch> <06188abbed359c266f2033d8b3b28aa0aaf8aada.1249999028.git.daniel.vetter@ffwll.ch> <3f8b26f517d6bea6dc326136b6e9ea9d210e9a5a.1249999028.git.daniel.vetter@ffwll.ch> <361705901f128de9afac9b43d386abf0be87a5b3.1249999028.git.daniel.vetter@ffwll.ch> In-Reply-To: References: Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 17/18] Implement drmmode overlay X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org This does not restore the overlay on EnterVT/disable it on LeaveVT. Does not look like this is necessary. Signed-off-by: Daniel Vetter --- src/drmmode_display.c | 9 +++ src/i830.h | 2 + src/i830_video.c | 190 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 184 insertions(+), 17 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 814743b..298804a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1130,3 +1130,12 @@ drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc) return drm_intel_get_pipe_from_crtc_id (bufmgr, drmmode_crtc->mode_crtc->crtc_id); } + +/* for the drmmode overlay */ +int +drmmode_crtc_id(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + return drmmode_crtc->mode_crtc->crtc_id; +} diff --git a/src/i830.h b/src/i830.h index 72edaa1..fe931ba 100644 --- a/src/i830.h +++ b/src/i830.h @@ -388,6 +388,7 @@ typedef struct _I830Rec { /* For Xvideo */ i830_memory *overlay_regs; + Bool use_drmmode_overlay; #ifdef INTEL_XVMC /* For XvMC */ Bool XvMCEnabled; @@ -692,6 +693,7 @@ void I830DRI2CloseScreen(ScreenPtr pScreen); extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp); extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc); extern int drmmode_output_dpms_status(xf86OutputPtr output); +extern int drmmode_crtc_id(xf86CrtcPtr crtc); extern Bool i830_crtc_on(xf86CrtcPtr crtc); extern int i830_crtc_to_pipe(xf86CrtcPtr crtc); diff --git a/src/i830_video.c b/src/i830_video.c index 80f7303..340f452 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -356,6 +356,138 @@ CompareOverlay(I830Ptr pI830, uint32_t * overlay, int size) static void I830SetOneLineModeRatio(ScrnInfoPtr pScrn); +/* kernel modesetting overlay functions */ +static Bool +drmmode_has_overlay(ScrnInfoPtr pScrn) +{ + I830Ptr p830 = I830PTR(pScrn); + struct drm_i915_getparam gp; + int has_overlay = 0; + + gp.param = I915_PARAM_HAS_OVERLAY; + gp.value = &has_overlay; + drmCommandWriteRead(p830->drmSubFD, DRM_I915_GETPARAM, + &gp, sizeof(gp)); + + return has_overlay ? TRUE : FALSE; +} + +static void +drmmode_overlay_update_attrs(ScrnInfoPtr pScrn) +{ + I830Ptr p830 = I830PTR(pScrn); + I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + struct drm_intel_overlay_attrs attrs; + int ret; + + attrs.flags = I915_OVERLAY_UPDATE_ATTRS; + attrs.brightness = pPriv->brightness; + attrs.contrast = pPriv->contrast; + attrs.saturation = pPriv->saturation; + attrs.color_key = pPriv->colorKey; + attrs.gamma0 = pPriv->gamma0; + attrs.gamma1 = pPriv->gamma1; + attrs.gamma2 = pPriv->gamma2; + attrs.gamma3 = pPriv->gamma3; + attrs.gamma4 = pPriv->gamma4; + attrs.gamma5 = pPriv->gamma5; + + ret = drmCommandWriteRead(p830->drmSubFD, DRM_I915_OVERLAY_ATTRS, + &attrs, sizeof(attrs)); + + if (ret != 0) + OVERLAY_DEBUG("overlay attrs ioctl failed: %i\n", ret); +} + +static void +drmmode_overlay_off(ScrnInfoPtr pScrn) +{ + I830Ptr p830 = I830PTR(pScrn); + struct drm_intel_overlay_put_image request; + int ret; + + request.flags = 0; + + ret = drmCommandWrite(p830->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE, + &request, sizeof(request)); + + if (ret != 0) + OVERLAY_DEBUG("overlay switch-off ioctl failed: %i\n", ret); +} + +static Bool +drmmode_overlay_put_image(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, + int id, short width, short height, + int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox, + short src_w, short src_h, short drw_w, short drw_h) +{ + I830Ptr p830 = I830PTR(pScrn); + I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + struct drm_intel_overlay_put_image request; + int ret; + int planar = is_planar_fourcc(id); + float scale; + + request.flags = I915_OVERLAY_ENABLE; + + request.bo_handle = pPriv->buf->handle; + if (planar) { + request.stride_Y = dstPitch*2; + request.stride_UV = dstPitch; + } else { + request.stride_Y = dstPitch; + request.stride_UV = 0; + } + request.offset_Y = pPriv->YBufOffset; + request.offset_U = pPriv->UBufOffset; + request.offset_V = pPriv->VBufOffset; + OVERLAY_DEBUG("off_Y: %i, off_U: %i, off_V: %i\n", request.offset_Y, + request.offset_U, request.offset_V); + + request.crtc_id = drmmode_crtc_id(crtc); + request.dst_x = dstBox->x1; + request.dst_y = dstBox->y1; + request.dst_width = dstBox->x2 - dstBox->x1; + request.dst_height = dstBox->y2 - dstBox->y1; + + request.src_width = width; + request.src_height = height; + /* adjust src dimensions */ + if (request.dst_height > 1) { + scale = ((float) request.dst_height - 1) / ((float) drw_h - 1); + request.src_scan_height = src_h * scale; + } else + request.src_scan_height = 1; + + if (request.dst_width > 1) { + scale = ((float) request.dst_width - 1) / ((float) drw_w - 1); + request.src_scan_width = src_w * scale; + } else + request.src_scan_width = 1; + + if (planar) { + request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420; + } else { + request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422; + if (id == FOURCC_UYVY) + request.flags |= I915_OVERLAY_Y_SWAP; + } + + ret = drmCommandWrite(p830->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE, + &request, sizeof(request)); + + /* drop the newly displaying buffer right away */ + drm_intel_bo_disable_reuse(pPriv->buf); + drm_intel_bo_unreference(pPriv->buf); + pPriv->buf = NULL; + + if (ret != 0) { + OVERLAY_DEBUG("overlay put-image ioctl failed: %i\n", ret); + return FALSE; + } else + return TRUE; +} + static void i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc) { @@ -597,15 +729,18 @@ I830InitVideo(ScreenPtr pScreen) } /* Set up overlay video if we can do it at this depth. */ - if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8 && - !pI830->use_drm_mode && pI830->overlay_regs != NULL) + if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8) { - overlayAdaptor = I830SetupImageVideoOverlay(pScreen); - if (overlayAdaptor != NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to set up overlay video\n"); + pI830->use_drmmode_overlay = drmmode_has_overlay(pScrn); + if ((!pI830->use_drm_mode && pI830->overlay_regs != NULL) + || pI830->use_drmmode_overlay) { + overlayAdaptor = I830SetupImageVideoOverlay(pScreen); + if (overlayAdaptor != NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to set up overlay video\n"); + } } } @@ -942,9 +1077,12 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) xvGamma5 = MAKE_ATOM("XV_GAMMA5"); } - /* XXX These two access the overlay regs, dont call with drmmode */ - I830ResetVideo(pScrn); - I830UpdateGamma(pScrn); + if (pI830->use_drmmode_overlay) + drmmode_overlay_update_attrs(pScrn); + else { + I830ResetVideo(pScrn); + I830UpdateGamma(pScrn); + } return adapt; } @@ -1052,6 +1190,7 @@ static void I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) { I830PortPrivPtr pPriv = (I830PortPrivPtr) data; + I830Ptr pI830 = I830PTR(pScrn); if (pPriv->textured) return; @@ -1062,7 +1201,10 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if (shutdown) { if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - ums_overlay_off(pScrn); + if (pI830->use_drmmode_overlay) + drmmode_overlay_off(pScrn); + else + ums_overlay_off(pScrn); } i830_free_video_buffers(pPriv); @@ -1191,7 +1333,10 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn, OVERLAY_DEBUG("GAMMA\n"); } - ums_overlay_update_attrs(pScrn, pPriv); + if (pI830->use_drmmode_overlay) + drmmode_overlay_update_attrs(pScrn); + else + ums_overlay_update_attrs(pScrn, pPriv); if (attribute == xvColorKey) REGION_EMPTY(pScrn->pScreen, &pPriv->clip); @@ -2108,7 +2253,11 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, if (!crtc) { pPriv->current_crtc = NULL; - ums_overlay_off(pScrn); + if (pI830->use_drmmode_overlay) + drmmode_overlay_off(pScrn); + else + ums_overlay_off(pScrn); + return TRUE; } @@ -2126,8 +2275,12 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, src_h = tmp; } - return ums_overlay_put_image(pScrn, crtc, id, width, height, dstPitch, - x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h); + if (pI830->use_drmmode_overlay) + return drmmode_overlay_put_image(pScrn, crtc, id, width, height, dstPitch, + x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h); + else + return ums_overlay_put_image(pScrn, crtc, id, width, height, dstPitch, + x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h); } static Bool @@ -2636,7 +2789,10 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout, /* Turn off the overlay */ OVERLAY_DEBUG("BLOCKHANDLER\n"); - ums_overlay_off (pScrn); + if (pI830->use_drmmode_overlay) + drmmode_overlay_off(pScrn); + else + ums_overlay_off (pScrn); pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = now + FREE_DELAY;