From ddb4e5d5dbf924d484ec088dc6f49d28496463b1 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 15 Dec 2008 14:27:45 +0000 Subject: src/glamo* : drag in the kdrive EXA sources, initial commit will need heavy editing. --- src/glamo-video.c | 910 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 910 insertions(+) create mode 100644 src/glamo-video.c (limited to 'src/glamo-video.c') diff --git a/src/glamo-video.c b/src/glamo-video.c new file mode 100644 index 0000000..c2f7cd2 --- /dev/null +++ b/src/glamo-video.c @@ -0,0 +1,910 @@ +/* + * Copyright © 2007 OpenMoko, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * authors: + * Dodji SEKETELI + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#ifdef XV + +#include "glamo.h" +#include "glamo-cmdq.h" +#include "glamo-draw.h" +#include "glamo-regs.h" +#include "glamo-log.h" +#include "kaa.h" + +#include +#include "fourcc.h" + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#define SYS_PITCH_ALIGN(w) (((w) + 3) & ~3) +#define VID_PITCH_ALIGN(w) (((w) + 1) & ~1) + +#define IMAGE_MAX_WIDTH 640 +#define IMAGE_MAX_HEIGHT 640 + +static void +GLAMOStopVideo(KdScreenInfo *screen, pointer data, Bool exit) +{ + ScreenPtr pScreen = screen->pScreen; + GLAMOPortPrivPtr pPortPriv = (GLAMOPortPrivPtr)data; + + + GLAMO_LOG("enter\n"); + + + /* + for (i = 0; i < GLAMO_VIDEO_NUM_BUFS; i++) + if (pPortPriv->off_screen[i]) { + KdOffscreenFree (pScreen, pPortPriv->off_screen[i]); + pPortPriv->off_screen[i] = 0; + } + */ + + + GLAMO_LOG("leave\n"); + +} + +static int +GLAMOSetPortAttribute(KdScreenInfo *screen, Atom attribute, int value, + pointer data) +{ + return BadMatch; +} + +static int +GLAMOGetPortAttribute(KdScreenInfo *screen, Atom attribute, int *value, + pointer data) +{ + return BadMatch; +} + +static void +GLAMOQueryBestSize(KdScreenInfo *screen, + Bool motion, + short vid_w, + short vid_h, + short drw_w, + short drw_h, + unsigned int *p_w, + unsigned int *p_h, + pointer data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + +static void +GLAMOVideoSave(ScreenPtr pScreen, KdOffscreenArea *area) +{ + KdScreenPriv(pScreen); + GLAMOScreenInfo(pScreenPriv); + GLAMOPortPrivPtr pPortPriv = glamos->pAdaptor->pPortPrivates[0].ptr; + int i; + + GLAMO_LOG("mark\n"); +} + +static Bool +GetYUVFrameByteSize (int fourcc_code, + unsigned short width, + unsigned short height, + unsigned int *size) +{ + if (!size) + return FALSE; + switch (fourcc_code) { + case FOURCC_YV12: + case FOURCC_I420: + *size = width*height * 3 / 2 ; + break; + default: + return FALSE; + } + return TRUE; + +} + +static Bool +GetYUVFrameAddresses (unsigned int frame_addr, + int fourcc_code, + unsigned short frame_width, + unsigned short frame_height, + unsigned short x, + unsigned short y, + unsigned int *y_addr, + unsigned int *u_addr, + unsigned int *v_addr) +{ + Bool is_ok = FALSE; + + if (!u_addr || !v_addr) { + GLAMO_LOG_ERROR("failed sanity check\n"); + goto out; + } + + + GLAMO_LOG("enter: frame(%dx%d), frame_addr:%#x\n" + "position:(%d,%d)\n", + frame_width, frame_height, + frame_addr, x, y); + + + switch (fourcc_code) { + case FOURCC_YV12: + *y_addr = frame_addr + x + y * frame_width; + *v_addr = frame_addr + frame_width*frame_height+ + x/2 + (y/2) *(frame_width/2); + *u_addr = frame_addr + frame_width*frame_height + + frame_width*frame_height/4 + + x/2 + (y/2)*(frame_width/2); + is_ok = TRUE; + break; + case FOURCC_I420: + *y_addr = frame_addr + x + y*frame_width; + *u_addr = frame_addr + frame_width*frame_height+ + x/2 + (y/2)*frame_width/2; + *v_addr = frame_addr + frame_width*frame_height + + frame_width*frame_height/4 + + x/2 + (y/2)*frame_height/2; + is_ok = TRUE; + break; + default: + is_ok = FALSE; + break; + } + + GLAMO_LOG("y_addr:%#x, u_addr:%#x, v_addr:%#x\n", + *y_addr, *u_addr, *v_addr); + +out: + + GLAMO_LOG("leave. is_ok:%d\n", + is_ok); + + return is_ok; +} + +/** + * copy a portion of the YUV frame "src_frame" to a destination in memory. + * The portion to copy is a rectangle located at (src_x,src_y), + * of size (rect_width,rect_height). + * + * @src_frame pointer to the start of the YUV frame to consider + * @frame_width width of the YUV frame + * @frame_height height of the YUV frame + * @src_x + * @src_y + * @rect_width + * @rect_height + */ +static Bool +CopyYUVPlanarFrameRect (const char *src_frame, + int fourcc_code, + unsigned short frame_width, + unsigned short frame_height, + unsigned short src_x, + unsigned short src_y, + unsigned short rect_width, + unsigned short rect_height, + char *destination) +{ + char *y_copy_src, *u_copy_src, *v_copy_src, + *y_copy_dst, *u_copy_dst, *v_copy_dst; + unsigned line; + Bool is_ok = FALSE; + + + GLAMO_LOG("enter. src_frame:%#x, code:%#x\n" + "frame(%d,%d)-(%dx%d), crop(%dx%d)\n" + "dest:%#x", + (unsigned)src_frame, (unsigned)fourcc_code, + src_x, src_y, frame_width, frame_height, + rect_width, rect_height, (unsigned)destination); + + + switch (fourcc_code) { + case FOURCC_YV12: + case FOURCC_I420: + /*planar yuv formats of the 4:2:0 family*/ + y_copy_src = (char*) src_frame + src_x + + frame_width*src_y; + u_copy_src = (char*) src_frame + + frame_width*frame_height + + src_x/2 + (frame_width/2)*(src_y/2); + v_copy_src = (char*) src_frame + + frame_width*frame_height*5/4 + src_x/2 + + (frame_width/2)*src_y/2; + y_copy_dst = destination; + u_copy_dst = destination + rect_width*rect_height; + v_copy_dst = destination + rect_width*rect_height*5/4; + + GLAMO_LOG("y_copy_src:%#x, " + "u_copy_src:%#x, " + "v_copy_src:%#x\n" + "y_copy_dst:%#x, " + "u_copy_dst:%#x, " + "v_copy_dst:%#x\n", + (unsigned)y_copy_src, + (unsigned)u_copy_src, + (unsigned)v_copy_src, + (unsigned)y_copy_dst, + (unsigned)u_copy_dst, + (unsigned)v_copy_dst); + + for (line = 0; line < rect_height; line++) { + + GLAMO_LOG("============\n" + "line:%d\n" + "============\n", + line); + GLAMO_LOG("y_copy_src:%#x, " + "y_copy_dst:%#x, \n", + (unsigned)y_copy_src, + (unsigned)y_copy_dst); + + + memcpy(y_copy_dst, + y_copy_src, + rect_width); + y_copy_src += frame_width; + y_copy_dst += rect_width; + + /* + * one line out of two has chrominance (u,v) + * sampling. + */ + if (!(line&1)) { + + GLAMO_LOG("u_copy_src:%#x, " + "u_copy_dst:%#x\n", + (unsigned)u_copy_src, + (unsigned)u_copy_dst); + + memcpy(u_copy_dst, + u_copy_src, + rect_width/2); + + GLAMO_LOG("v_copy_src:%#x, " + "v_copy_dst:%#x\n", + (unsigned)v_copy_src, + (unsigned)v_copy_dst); + + memcpy(v_copy_dst, + v_copy_src, + rect_width/2); + u_copy_src += frame_width/2; + u_copy_dst += rect_width/2; + v_copy_src += frame_width/2; + v_copy_dst += rect_width/2; + } + } + break; + default: + /* + * glamo 3362 only supports YUV 4:2:0 planar formats. + */ + is_ok = FALSE; + goto out; + } + is_ok = TRUE; +out: + + GLAMO_LOG("leave.is_ok:%d\n", is_ok); + + return is_ok; +} + +static Bool +GLAMOVideoUploadFrameToOffscreen (KdScreenInfo *screen, + unsigned char *yuv_frame, + int fourcc_code, + unsigned yuv_frame_width, + unsigned yuv_frame_height, + short src_x, short src_y, + short src_w, short src_h, + GLAMOPortPrivPtr portPriv, + unsigned int *out_offscreen_frame) +{ + int idx = 0; + unsigned size = 0; + Bool is_ok = FALSE; + ScreenPtr pScreen = screen->pScreen; + char *offscreen_frame = NULL; + + + GLAMO_LOG("enter. frame(%dx%d), crop(%dx%d)\n", + yuv_frame_width, yuv_frame_height, + src_w, src_h); + + + if (!GetYUVFrameByteSize (fourcc_code, src_w, src_h, &size)) { + GLAMO_LOG_ERROR("failed to get frame size\n"); + goto out; + } + + if (!portPriv->off_screen_yuv_buf + || size < portPriv->off_screen_yuv_buf->size) { + if (portPriv->off_screen_yuv_buf) { + KdOffscreenFree(pScreen, + portPriv->off_screen_yuv_buf); + } + portPriv->off_screen_yuv_buf = + KdOffscreenAlloc(pScreen, size, VID_PITCH_ALIGN(2), + TRUE, GLAMOVideoSave, portPriv); + if (!portPriv->off_screen_yuv_buf) { + GLAMO_LOG_ERROR("failed to allocate " + "offscreen memory\n"); + goto out; + } + + GLAMO_LOG("allocated %d bytes of offscreen memory\n", size); + + } + offscreen_frame = screen->memory_base + + portPriv->off_screen_yuv_buf->offset; + + if (out_offscreen_frame) + *out_offscreen_frame = portPriv->off_screen_yuv_buf->offset; + + if (!CopyYUVPlanarFrameRect (yuv_frame, fourcc_code, + yuv_frame_width, yuv_frame_height, + src_x, src_y, src_w, src_h, + offscreen_frame)) { + GLAMO_LOG_ERROR("failed to copy yuv " + "frame to offscreen memory\n"); + goto out; + } + + is_ok = TRUE; +out: + + + GLAMO_LOG("leave:%d\n", is_ok); + + return is_ok; + +} + +static void +GLAMODisplayYUVPlanarFrameRegion (ScreenPtr pScreen, + unsigned int yuv_frame_addr, + int fourcc_code, + short frame_width, + short frame_height, + unsigned int dst_addr, + short dst_pitch, + unsigned short scale_w, + unsigned short scale_h, + RegionPtr clipping_region, + BoxPtr dst_box) +{ + BoxPtr rect = NULL; + int num_rects = 0; + int i =0; + int dst_width = 0, dst_height = 0; + unsigned int y_addr = 0, u_addr = 0, v_addr = 0, + src_x, src_y, src_w, src_h, dest_addr; + + GLAMO_RETURN_IF_FAIL(clipping_region && dst_box); + + + GLAMO_LOG("enter: frame addr:%#x, fourcc:%#x, \n" + "frame:(%dx%d), dst_addr:%#x, dst_pitch:%hd\n" + "scale:(%hd,%hd), dst_box(%d,%d)\n", + yuv_frame_addr, fourcc_code, frame_width, frame_height, + dst_addr, dst_pitch, scale_w, scale_h, + dst_box->x1, dst_box->y1); + + + GLAMO_RETURN_IF_FAIL(clipping_region); + rect = REGION_RECTS(clipping_region); + num_rects = REGION_NUM_RECTS(clipping_region); + + GLAMO_LOG("num_rects to display:%d\n", num_rects); + + for (i = 0; i < num_rects; i++, rect++) { + + GLAMO_LOG("rect num:%d, (%d,%d,%d,%d)\n", + i, + rect->x1, rect->y1, + rect->x2, rect->y2); + + dst_width = abs(rect->x2 - rect->x1); + dst_height = abs(rect->y2 - rect->y1); + dest_addr = dst_addr + rect->x1*2 + rect->y1*dst_pitch; + src_w = (dst_width * scale_w) >> 11; + src_h = (dst_height * scale_h) >> 11; + src_x = ((abs(rect->x1 - dst_box->x1) * scale_w) >> 11); + src_y = ((abs(rect->y1 - dst_box->y1) * scale_h) >> 11); + + GLAMO_LOG("matching src rect:(%d,%d)-(%dx%d)\n", + + src_x,src_y, src_w, src_h); + + if (!GetYUVFrameAddresses (yuv_frame_addr, + fourcc_code, + frame_width, + frame_height, + src_x, + src_y, + &y_addr, + &u_addr, + &v_addr)) { + GLAMO_LOG_ERROR("failed to get yuv frame @\n"); + continue; + } + GLAMOISPDisplayYUVPlanarFrame(pScreen, + y_addr, + u_addr, + v_addr, + frame_width, + frame_width/2, + src_w, src_h, + dest_addr, + dst_pitch, + dst_width, dst_height, + scale_w, scale_h); + } + + GLAMO_LOG("leave\n"); + +} + +static void +GLAMODisplayFrame (KdScreenInfo *screen, + GLAMOPortPrivPtr portPriv) +{ + GLAMOVideoFrameDisplayInfo *info; + BoxRec dst_box; + unsigned int dest_w, dest_h, dest_frame_addr; + unsigned short scale_w, scale_h; + PixmapPtr dest_pixmap; + ScreenPtr pScreen; + + + GLAMO_LOG("enter\n"); + + + GLAMO_RETURN_IF_FAIL (screen + && screen->pScreen + && portPriv); + + info = &portPriv->frame_display_info; + + GLAMO_RETURN_IF_FAIL (info + && info->dest_drawable); + + if (info->dest_drawable->type == DRAWABLE_WINDOW) { + dest_pixmap = + (*screen->pScreen->GetWindowPixmap) + ((WindowPtr)info->dest_drawable); + } else { + dest_pixmap = (PixmapPtr)info->dest_drawable; + } + dest_frame_addr = + (CARD8*)dest_pixmap->devPrivate.ptr - screen->memory_base; + + dest_w = abs(info->dest_box.x2 - info->dest_box.x1); + dest_h = abs(info->dest_box.y2 - info->dest_box.y1); + scale_w = (info->src_w << 11)/dest_w; + scale_h = (info->src_h << 11)/dest_h; + + GLAMODisplayYUVPlanarFrameRegion(screen->pScreen, + info->offscreen_frame_addr, + info->id, + info->src_w, info->src_h, + dest_frame_addr, + dest_pixmap->devKind, + scale_w, scale_h, + &info->clipped_dest_region, + &info->dest_box); + + GLAMO_LOG("leave\n"); + +} + +static int +GLAMOPutImage(KdScreenInfo *screen, DrawablePtr dst_drawable, + 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) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + GLAMOCardInfo(pScreenPriv); + GLAMOPortPrivPtr portPriv = (GLAMOPortPrivPtr)data; + GLAMOVideoFrameDisplayInfo *info = NULL; + unsigned short scale_w, scale_h; + unsigned int offscreen_frame_addr = 0, dst_addr = 0; + PixmapPtr dst_pixmap; + RegionRec dst_reg; + + + GLAMO_LOG("enter. id:%#x, frame:(%dx%d) srccrop:(%d,%d)-(%dx%d)\n" + "dst geo:(%d,%d)-(%dx%d)\n", + id, width, height, src_x, src_y, src_w, src_h, + drw_x, drw_y, drw_w, drw_h); + + /* + * upload the YUV frame to offscreen vram so that GLAMO can + * later have access to it and blit it from offscreen vram to + * onscreen vram. + */ + if (!GLAMOVideoUploadFrameToOffscreen(screen, buf, id, + width, height, + src_x, src_y, src_w, src_h, + portPriv, + &offscreen_frame_addr)) { + GLAMO_LOG("failed to upload frame to offscreen\n"); + return BadAlloc; + } + + GLAMO_LOG("copied video frame to vram offset:%#x\n", + offscreen_frame_addr); + GLAMO_LOG("y_pitch:%hd, crop(%hdx%hd)\n", src_w, src_w, src_h); + + + /* + * Save the information necessary to display the video frame + * - that has been uploaded to offscreen vram - in portPriv. + * That way, we can later display that very same frame from + * within other driver calls like ReputImage. + */ + info = &portPriv->frame_display_info; + memset(&dst_reg, 0, sizeof(dst_reg)); + + info->offscreen_frame_addr = offscreen_frame_addr; + info->id = id; + info->src_w = src_w; + info->src_h = src_h; + info->dest_drawable = dst_drawable; + info->drw_w = drw_w; + info->drw_h = drw_h; + info->dest_box.x1 = drw_x; + info->dest_box.y1 = drw_y; + info->dest_box.x2 = drw_x + drw_w; + info->dest_box.y2 = drw_y + drw_h; + REGION_INIT(pScreen, &dst_reg, &info->dest_box, 0); + REGION_INTERSECT(pScreen, &info->clipped_dest_region, + &dst_reg, clipBoxes); + REGION_UNINIT(pScreen, &dst_reg); + GLAMO_RETURN_VAL_IF_FAIL(REGION_NOTEMPTY(pScreen, + &info->clipped_dest_region), + BadImplementation); + + /* + * Okay now that we did save all the information necessary to + * display the video frame in portPriv, let's display the frame. + */ + GLAMODisplayFrame(screen, portPriv); + + + GLAMO_LOG("leave\n"); + + return Success; +} + +static int +GLAMOReputImage(KdScreenInfo *screen, + DrawablePtr dest_drawable, + short drw_x, short drw_y, + RegionPtr clipBoxes, + pointer data) +{ + ScreenPtr pScreen = screen->pScreen; + GLAMOPortPrivPtr portPriv = (GLAMOPortPrivPtr)data; + RegionRec dst_reg; + + + GLAMO_LOG("enter\n"); + + + GLAMO_RETURN_VAL_IF_FAIL(portPriv + && screen + && dest_drawable + && clipBoxes, + BadImplementation); + GLAMOVideoFrameDisplayInfo *info = &portPriv->frame_display_info; + memset(&dst_reg, 0, sizeof(dst_reg)); + + info->dest_box.x1 = drw_x; + info->dest_box.y1 = drw_y; + info->dest_box.x2 = drw_x + info->drw_w; + info->dest_box.y2 = drw_y + info->drw_h; + REGION_INIT(pScreen, &dst_reg, &info->dest_box, 0); + REGION_INTERSECT(pScreen, &info->clipped_dest_region, + &dst_reg, clipBoxes); + REGION_UNINIT(pScreen, &dst_reg); + GLAMO_RETURN_VAL_IF_FAIL(REGION_NOTEMPTY(pScreen, + &info->clipped_dest_region), + BadImplementation); + GLAMODisplayFrame(screen, portPriv); + + GLAMO_LOG("leave\n"); + + return Success; +} + +static int +GLAMOQueryImageAttributes(KdScreenInfo *screen, int id, unsigned short *w, + unsigned short *h, int *pitches, int *offsets) +{ + int size, tmp; + + if (*w > IMAGE_MAX_WIDTH) + *w = IMAGE_MAX_WIDTH; + if (*h > IMAGE_MAX_HEIGHT) + *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if (offsets) + offsets[0] = 0; + + switch (id) + { + case FOURCC_YV12: + case FOURCC_I420: + *h = (*h + 1) & ~1; + + tmp = SYS_PITCH_ALIGN(*w); + size = tmp * *h; + + if (pitches) + pitches[0] = tmp; + if (offsets) + offsets[1] = size; + + tmp = SYS_PITCH_ALIGN(*w / 2); + size += tmp * *h / 2; + if (pitches) + pitches[1] = pitches[2] = tmp; + if (offsets) + offsets[2] = size; + + size += tmp * *h / 2; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if (pitches) + pitches[0] = size; + size *= *h; + break; + } + + return size; +} + + +/* client libraries expect an encoding */ +static KdVideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 1 + +static KdVideoFormatRec Formats[NUM_FORMATS] = +{ + {16, TrueColor} +}; + +#define NUM_ATTRIBUTES 0 +static KdAttributeRec Attributes[NUM_ATTRIBUTES] = +{ +}; + +static KdImageRec Images[] = +{ + XVIMAGE_YV12, + XVIMAGE_I420, +}; +#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])) + +static KdVideoAdaptorPtr +GLAMOSetupImageVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + GLAMOScreenInfo(pScreenPriv); + KdVideoAdaptorPtr adapt; + GLAMOPortPrivPtr portPriv; + int i; + + GLAMO_LOG("enter\n"); + glamos->num_texture_ports = 1; + + adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) + + glamos->num_texture_ports * + (sizeof(GLAMOPortPrivRec) + sizeof(DevUnion))); + if (adapt == NULL) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "GLAMO Texture Video"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = glamos->num_texture_ports; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + portPriv = (GLAMOPortPrivPtr) + (&adapt->pPortPrivates[glamos->num_texture_ports]); + + for (i = 0; i < glamos->num_texture_ports; i++) + adapt->pPortPrivates[i].ptr = &portPriv[i]; + + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pAttributes = Attributes; + adapt->pImages = Images; + adapt->nImages = NUM_IMAGES; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = GLAMOStopVideo; + adapt->SetPortAttribute = GLAMOSetPortAttribute; + adapt->GetPortAttribute = GLAMOGetPortAttribute; + adapt->QueryBestSize = GLAMOQueryBestSize; + adapt->PutImage = GLAMOPutImage; + adapt->ReputImage = GLAMOReputImage; + adapt->QueryImageAttributes = GLAMOQueryImageAttributes; + + for (i = 0; i < glamos->num_texture_ports; i++) { + REGION_INIT(pScreen, &portPriv[i].clip, NullBox, 0); + portPriv[i].color_key = 0xffff; + } + + glamos->pAdaptor = adapt; + + GLAMO_LOG("leave. adaptor:%#x\n", (unsigned)adapt); + + return adapt; +} + +Bool +GLAMOInitVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + GLAMOScreenInfo(pScreenPriv); + GLAMOCardInfo(pScreenPriv); + KdScreenInfo *screen = pScreenPriv->screen; + KdVideoAdaptorPtr *oldAdaptors = NULL, *newAdaptors = NULL; + KdVideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + Bool is_ok = FALSE; + + GLAMO_LOG("enter\n"); + + glamos->pAdaptor = NULL; + + if (glamoc->reg_base == NULL) { + GLAMO_LOG("glamoc->reg_base is null\n"); + goto out; + } + + num_adaptors = KdXVListGenericAdaptors(screen, &oldAdaptors); + + newAdaptor = GLAMOSetupImageVideo(pScreen); + + if (newAdaptor) { + if (!num_adaptors) { + num_adaptors = 1; + newAdaptors = &newAdaptor; + } else { + newAdaptors = xalloc((num_adaptors + 1) * + sizeof(KdVideoAdaptorPtr *)); + if (!newAdaptors) + goto out; + + memcpy(newAdaptors, + oldAdaptors, + num_adaptors * sizeof(KdVideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + num_adaptors++; + } + } + + GLAMOCMDQCacheSetup(pScreen); + GLAMOISPEngineInit(pScreen); + + if (num_adaptors) + KdXVScreenInit(pScreen, newAdaptors, num_adaptors); + + is_ok = TRUE; +out: + GLAMO_LOG("leave. is_ok:%d, adaptors:%d\n", + is_ok, num_adaptors); + /* + if (newAdaptors) { + xfree(newAdaptors); + } + */ + return is_ok; +} + +void +GLAMOFiniVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + GLAMOScreenInfo(pScreenPriv); + KdVideoAdaptorPtr adapt = glamos->pAdaptor; + GLAMOPortPrivPtr portPriv; + int i; + + GLAMO_LOG ("enter\n"); + + if (!adapt) + return; + + for (i = 0; i < glamos->num_texture_ports; i++) { + portPriv = (GLAMOPortPrivPtr)(adapt->pPortPrivates[i].ptr); + GLAMO_LOG("freeing clipping region...\n"); + REGION_UNINIT(pScreen, &portPriv->clip); + GLAMO_LOG("freed clipping region\n"); + if (portPriv->off_screen_yuv_buf) { + GLAMO_LOG("freeing offscreen yuv buf...\n"); + KdOffscreenFree(pScreen, + portPriv->off_screen_yuv_buf); + portPriv->off_screen_yuv_buf = NULL; + GLAMO_LOG("freeed offscreen yuv buf\n"); + } + REGION_UNINIT + (pScreen, + &portPriv->frame_display_info.clipped_dest_region); + } + xfree(adapt); + glamos->pAdaptor = NULL; + GLAMO_LOG ("leave\n"); +} + +void +GLAMOVideoTeardown(ScreenPtr pScreen) +{ + GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP); + GLAMOEngineDisable(pScreen, GLAMO_ENGINE_ISP); +} + +#endif /*XV*/ -- cgit v1.2.3