diff options
author | Keith Packard <keithp@keithp.com> | 2014-07-24 10:27:55 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2014-09-12 13:51:14 -0700 |
commit | 616dea2c67847101fd43b5d89b556b3702c7f0bb (patch) | |
tree | bdcd3e4ec057deeab433f4958e2483cdb2c4074a /src/uxa/intel_uxa_video.c | |
parent | 57c67199d043f3a653436769f1a69947a96d9d5b (diff) |
Rename uxa-specific functions and structs
This starts to separate uxa from the rest of the driver by renaming
uxa-specific functions and structs to make it clear which portions of
the driver are uxa-specific and which are common.
Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/uxa/intel_uxa_video.c')
-rw-r--r-- | src/uxa/intel_uxa_video.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/src/uxa/intel_uxa_video.c b/src/uxa/intel_uxa_video.c new file mode 100644 index 00000000..7ff909ff --- /dev/null +++ b/src/uxa/intel_uxa_video.c @@ -0,0 +1,389 @@ +/*************************************************************************** + + Copyright 2000 Intel Corporation. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sub license, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **************************************************************************/ + +/* + * i830_video.c: i830/i845 Xv driver. + * + * Copyright © 2002 by Alan Hourihane and David Dawes + * + * Authors: + * Alan Hourihane <alanh@tungstengraphics.com> + * David Dawes <dawes@xfree86.org> + * + * Derived from i810 Xv driver: + * + * Authors of i810 code: + * Jonathan Bian <jonathan.bian@intel.com> + * Offscreen Images: + * Matt Sottek <matthew.j.sottek@intel.com> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <inttypes.h> +#include <math.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "xf86drm.h" +#include "regionstr.h" +#include "randrstr.h" +#include "windowstr.h" +#include "damage.h" +#include "intel.h" +#include "intel_video.h" +#include "i830_reg.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#include "dixstruct.h" +#include "fourcc.h" + +#ifdef INTEL_XVMC +#define _INTEL_XVMC_SERVER_ +#include "intel_xvmc.h" +#endif +#include "intel_glamor.h" + +/* overlay debugging printf function */ +#if 0 +#define UXA_VIDEO_DEBUG ErrorF +#else +#define UXA_VIDEO_DEBUG if (0) ErrorF +#endif + +static int intel_uxa_video_put_image_textured(ScrnInfoPtr, short, short, short, short, short, short, + short, short, int, unsigned char *, short, short, + Bool, RegionPtr, pointer, DrawablePtr); + +static int +intel_uxa_video_set_port_attribute(ScrnInfoPtr scrn, + Atom attribute, INT32 value, pointer data) +{ + intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; + + if (attribute == intel_xv_Brightness) { + if ((value < -128) || (value > 127)) + return BadValue; + adaptor_priv->brightness = value; + return Success; + } else if (attribute == intel_xv_Contrast) { + if ((value < 0) || (value > 255)) + return BadValue; + adaptor_priv->contrast = value; + return Success; + } else if (attribute == intel_xv_SyncToVblank) { + if ((value < -1) || (value > 1)) + return BadValue; + adaptor_priv->SyncToVblank = value; + return Success; + } else { + return BadMatch; + } +} + + +static int xvmc_passthrough(int id) +{ +#ifdef INTEL_XVMC + return id == FOURCC_XVMC; +#else + return 0; +#endif +} + + +static void +intel_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap, + xf86CrtcPtr crtc, RegionPtr clipBoxes) +{ + intel_screen_private *intel = intel_get_screen_private(scrn); + pixman_box16_t box, crtc_box; + int pipe, event; + Bool full_height; + int y1, y2; + + pipe = -1; + if (scrn->vtSema && pixmap_is_scanout(pixmap)) + pipe = intel_crtc_to_pipe(crtc); + if (pipe < 0) + return; + + box = *REGION_EXTENTS(unused, clipBoxes); + + if (crtc->transform_in_use) + pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, &box); + + /* We could presume the clip was correctly computed... */ + intel_crtc_box(crtc, &crtc_box); + intel_box_intersect(&box, &crtc_box, &box); + + /* + * Make sure we don't wait for a scanline that will + * never occur + */ + y1 = (crtc_box.y1 <= box.y1) ? box.y1 - crtc_box.y1 : 0; + y2 = (box.y2 <= crtc_box.y2) ? + box.y2 - crtc_box.y1 : crtc_box.y2 - crtc_box.y1; + if (y2 <= y1) + return; + + full_height = FALSE; + if (y1 == 0 && y2 == (crtc_box.y2 - crtc_box.y1)) + full_height = TRUE; + + /* + * Pre-965 doesn't have SVBLANK, so we need a bit + * of extra time for the blitter to start up and + * do its job for a full height blit + */ + if (full_height && INTEL_INFO(intel)->gen < 040) + y2 -= 2; + + if (pipe == 0) { + pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; + event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; + if (full_height && INTEL_INFO(intel)->gen >= 040) + event = MI_WAIT_FOR_PIPEA_SVBLANK; + } else { + pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; + event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; + if (full_height && INTEL_INFO(intel)->gen >= 040) + event = MI_WAIT_FOR_PIPEB_SVBLANK; + } + + if (crtc->mode.Flags & V_INTERLACE) { + /* DSL count field lines */ + y1 /= 2; + y2 /= 2; + } + + BEGIN_BATCH(5); + /* The documentation says that the LOAD_SCAN_LINES command + * always comes in pairs. Don't ask me why. */ + OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe); + OUT_BATCH((y1 << 16) | (y2-1)); + OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe); + OUT_BATCH((y1 << 16) | (y2-1)); + OUT_BATCH(MI_WAIT_FOR_EVENT | event); + ADVANCE_BATCH(); +} + +/* + * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h). + * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h). + * id is a fourcc code for the format of the video. + * buf is the pointer to the source data in system memory. + * width and height are the w/h of the source data. + * If "sync" is TRUE, then we must be finished with *buf at the point of return + * (which we always are). + * clipBoxes is the clipping region in screen space. + * data is a pointer to our port private. + * drawable is some Drawable, which might not be the screen in the case of + * compositing. It's a new argument to the function in the 1.1 server. + */ +static int +intel_uxa_video_put_image_textured(ScrnInfoPtr scrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char *buf, + short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data, + DrawablePtr drawable) +{ + intel_screen_private *intel = intel_get_screen_private(scrn); + intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; + PixmapPtr pixmap = get_drawable_pixmap(drawable); + int dstPitch, dstPitch2; + BoxRec dstBox; + xf86CrtcPtr crtc; + int top, left, npixels, nlines; + + if (!intel_uxa_pixmap_is_offscreen(pixmap)) + return BadAlloc; + +#if 0 + ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" + "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, + drw_y, drw_w, drw_h, width, height); +#endif + + if (!intel_clip_video_helper(scrn, + adaptor_priv, + &crtc, + &dstBox, + src_x, src_y, drw_x, drw_y, + src_w, src_h, drw_w, drw_h, + id, + &top, &left, &npixels, &nlines, clipBoxes, + width, height)) + return Success; + + if (xvmc_passthrough(id)) { + uint32_t *gem_handle = (uint32_t *)buf; + int size; + + intel_setup_dst_params(scrn, adaptor_priv, width, height, + &dstPitch, &dstPitch2, &size, id); + + if (IS_I915G(intel) || IS_I915GM(intel)) { + /* XXX: i915 is not support and needs some + * serious care. grep for KMS in i915_hwmc.c */ + return BadAlloc; + } + + if (adaptor_priv->buf) + drm_intel_bo_unreference(adaptor_priv->buf); + + adaptor_priv->buf = + drm_intel_bo_gem_create_from_name(intel->bufmgr, + "xvmc surface", + *gem_handle); + if (adaptor_priv->buf == NULL) + return BadAlloc; + + adaptor_priv->reusable = FALSE; + } else { + if (!intel_video_copy_data(scrn, adaptor_priv, width, height, + &dstPitch, &dstPitch2, + top, left, npixels, nlines, id, buf)) + return BadAlloc; + } + + if (crtc && adaptor_priv->SyncToVblank != 0 && INTEL_INFO(intel)->gen < 060) { + intel_wait_for_scanline(scrn, pixmap, crtc, clipBoxes); + } + + if (INTEL_INFO(intel)->gen >= 060) { + Gen6DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, + width, height, dstPitch, dstPitch2, + src_w, src_h, + drw_w, drw_h, pixmap); + } else if (INTEL_INFO(intel)->gen >= 040) { + I965DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, + width, height, dstPitch, dstPitch2, + src_w, src_h, + drw_w, drw_h, pixmap); + } else { + I915DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, + width, height, dstPitch, dstPitch2, + src_w, src_h, drw_w, drw_h, + pixmap); + } + + intel_get_screen_private(scrn)->needs_flush = TRUE; + DamageDamageRegion(drawable, clipBoxes); + + /* And make sure the WAIT_FOR_EVENT is queued before any + * modesetting/dpms operations on the pipe. + */ + intel_batch_submit(scrn); + + return Success; +} + +XF86VideoAdaptorPtr intel_uxa_video_setup_image_textured(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + intel_screen_private *intel = intel_get_screen_private(scrn); + XF86VideoAdaptorPtr adapt; + intel_adaptor_private *adaptor_privs; + DevUnion *devUnions; + int nports = 16, i; + + UXA_VIDEO_DEBUG("intel_video_overlay_setup_image\n"); + + adapt = calloc(1, sizeof(XF86VideoAdaptorRec)); + adaptor_privs = calloc(nports, sizeof(intel_adaptor_private)); + devUnions = calloc(nports, sizeof(DevUnion)); + if (adapt == NULL || adaptor_privs == NULL || devUnions == NULL) { + free(adapt); + free(adaptor_privs); + free(devUnions); + return NULL; + } + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = 0; + adapt->name = "Intel(R) Textured Video"; + adapt->nEncodings = 1; + adapt->pEncodings = xnfalloc(sizeof(intel_xv_dummy_encoding)); + memcpy(adapt->pEncodings, intel_xv_dummy_encoding, sizeof(intel_xv_dummy_encoding)); + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = intel_xv_formats; + adapt->nPorts = nports; + adapt->pPortPrivates = devUnions; + adapt->nAttributes = 0; + adapt->pAttributes = NULL; + if (IS_I915G(intel) || IS_I915GM(intel)) + adapt->nImages = NUM_IMAGES - XVMC_IMAGE; + else + adapt->nImages = NUM_IMAGES; + + adapt->pImages = intel_xv_images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = intel_video_stop_video; + adapt->SetPortAttribute = intel_uxa_video_set_port_attribute; + adapt->GetPortAttribute = intel_video_get_port_attribute; + adapt->QueryBestSize = intel_video_query_best_size; + adapt->PutImage = intel_uxa_video_put_image_textured; + adapt->QueryImageAttributes = intel_video_query_image_attributes; + + for (i = 0; i < nports; i++) { + intel_adaptor_private *adaptor_priv = &adaptor_privs[i]; + + adaptor_priv->textured = TRUE; + adaptor_priv->videoStatus = 0; + adaptor_priv->buf = NULL; + adaptor_priv->old_buf[0] = NULL; + adaptor_priv->old_buf[1] = NULL; + + adaptor_priv->rotation = RR_Rotate_0; + adaptor_priv->SyncToVblank = 1; + + /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */ + REGION_NULL(screen, &adaptor_priv->clip); + + adapt->pPortPrivates[i].ptr = (pointer) (adaptor_priv); + } + + intel_xv_SyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); + + return adapt; +} |