Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 Younes Manton og Thomas Balling Sørensen.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "pipe/p_compiler.h"
  29.  
  30. #include "util/u_memory.h"
  31. #include "util/u_debug.h"
  32. #include "util/u_sampler.h"
  33.  
  34. #include "vdpau_private.h"
  35.  
  36. /**
  37.  * Create a VdpDevice object for use with X11.
  38.  */
  39. PUBLIC VdpStatus
  40. vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device,
  41.                           VdpGetProcAddress **get_proc_address)
  42. {
  43.    struct pipe_screen *pscreen;
  44.    vlVdpDevice *dev = NULL;
  45.    VdpStatus ret;
  46.  
  47.    if (!(display && device && get_proc_address))
  48.       return VDP_STATUS_INVALID_POINTER;
  49.  
  50.    if (!vlCreateHTAB()) {
  51.       ret = VDP_STATUS_RESOURCES;
  52.       goto no_htab;
  53.    }
  54.  
  55.    dev = CALLOC(1, sizeof(vlVdpDevice));
  56.    if (!dev) {
  57.       ret = VDP_STATUS_RESOURCES;
  58.       goto no_dev;
  59.    }
  60.  
  61.    dev->vscreen = vl_screen_create(display, screen);
  62.    if (!dev->vscreen) {
  63.       ret = VDP_STATUS_RESOURCES;
  64.       goto no_vscreen;
  65.    }
  66.  
  67.    pscreen = dev->vscreen->pscreen;
  68.    dev->context = pscreen->context_create(pscreen, dev->vscreen);
  69.    if (!dev->context) {
  70.       ret = VDP_STATUS_RESOURCES;
  71.       goto no_context;
  72.    }
  73.  
  74.    *device = vlAddDataHTAB(dev);
  75.    if (*device == 0) {
  76.       ret = VDP_STATUS_ERROR;
  77.       goto no_handle;
  78.    }
  79.  
  80.    vl_compositor_init(&dev->compositor, dev->context);
  81.    pipe_mutex_init(dev->mutex);
  82.  
  83.    *get_proc_address = &vlVdpGetProcAddress;
  84.  
  85.    return VDP_STATUS_OK;
  86.  
  87. no_handle:
  88.    /* Destroy vscreen */
  89. no_context:
  90.    vl_screen_destroy(dev->vscreen);
  91. no_vscreen:
  92.    FREE(dev);
  93. no_dev:
  94.    vlDestroyHTAB();
  95. no_htab:
  96.    return ret;
  97. }
  98.  
  99. /**
  100.  * Create a VdpPresentationQueueTarget for use with X11.
  101.  */
  102. PUBLIC VdpStatus
  103. vlVdpPresentationQueueTargetCreateX11(VdpDevice device, Drawable drawable,
  104.                                       VdpPresentationQueueTarget *target)
  105. {
  106.    vlVdpPresentationQueueTarget *pqt;
  107.    VdpStatus ret;
  108.  
  109.    if (!drawable)
  110.       return VDP_STATUS_INVALID_HANDLE;
  111.  
  112.    vlVdpDevice *dev = vlGetDataHTAB(device);
  113.    if (!dev)
  114.       return VDP_STATUS_INVALID_HANDLE;
  115.  
  116.    pqt = CALLOC(1, sizeof(vlVdpPresentationQueue));
  117.    if (!pqt)
  118.       return VDP_STATUS_RESOURCES;
  119.  
  120.    pqt->device = dev;
  121.    pqt->drawable = drawable;
  122.  
  123.    *target = vlAddDataHTAB(pqt);
  124.    if (*target == 0) {
  125.       ret = VDP_STATUS_ERROR;
  126.       goto no_handle;
  127.    }
  128.  
  129.    return VDP_STATUS_OK;
  130.  
  131. no_handle:
  132.    FREE(pqt);
  133.    return ret;
  134. }
  135.  
  136. /**
  137.  * Destroy a VdpPresentationQueueTarget.
  138.  */
  139. VdpStatus
  140. vlVdpPresentationQueueTargetDestroy(VdpPresentationQueueTarget presentation_queue_target)
  141. {
  142.    vlVdpPresentationQueueTarget *pqt;
  143.  
  144.    pqt = vlGetDataHTAB(presentation_queue_target);
  145.    if (!pqt)
  146.       return VDP_STATUS_INVALID_HANDLE;
  147.  
  148.    vlRemoveDataHTAB(presentation_queue_target);
  149.    FREE(pqt);
  150.  
  151.    return VDP_STATUS_OK;
  152. }
  153.  
  154. /**
  155.  * Destroy a VdpDevice.
  156.  */
  157. VdpStatus
  158. vlVdpDeviceDestroy(VdpDevice device)
  159. {
  160.    vlVdpDevice *dev = vlGetDataHTAB(device);
  161.    if (!dev)
  162.       return VDP_STATUS_INVALID_HANDLE;
  163.  
  164.    pipe_mutex_destroy(dev->mutex);
  165.    vl_compositor_cleanup(&dev->compositor);
  166.    dev->context->destroy(dev->context);
  167.    vl_screen_destroy(dev->vscreen);
  168.  
  169.    vlRemoveDataHTAB(device);
  170.    FREE(dev);
  171.    vlDestroyHTAB();
  172.  
  173.    return VDP_STATUS_OK;
  174. }
  175.  
  176. /**
  177.  * Retrieve a VDPAU function pointer.
  178.  */
  179. VdpStatus
  180. vlVdpGetProcAddress(VdpDevice device, VdpFuncId function_id, void **function_pointer)
  181. {
  182.    vlVdpDevice *dev = vlGetDataHTAB(device);
  183.    if (!dev)
  184.       return VDP_STATUS_INVALID_HANDLE;
  185.  
  186.    if (!function_pointer)
  187.       return VDP_STATUS_INVALID_POINTER;
  188.  
  189.    if (!vlGetFuncFTAB(function_id, function_pointer))
  190.       return VDP_STATUS_INVALID_FUNC_ID;
  191.  
  192.    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Got proc adress %p for id %d\n", *function_pointer, function_id);
  193.  
  194.    return VDP_STATUS_OK;
  195. }
  196.  
  197. #define _ERROR_TYPE(TYPE,STRING) case TYPE: return STRING;
  198.  
  199. /**
  200.  * Retrieve a string describing an error code.
  201.  */
  202. char const *
  203. vlVdpGetErrorString (VdpStatus status)
  204. {
  205.    switch (status) {
  206.    _ERROR_TYPE(VDP_STATUS_OK,"The operation completed successfully; no error.");
  207.    _ERROR_TYPE(VDP_STATUS_NO_IMPLEMENTATION,"No backend implementation could be loaded.");
  208.    _ERROR_TYPE(VDP_STATUS_DISPLAY_PREEMPTED,"The display was preempted, or a fatal error occurred. The application must re-initialize VDPAU.");
  209.    _ERROR_TYPE(VDP_STATUS_INVALID_HANDLE,"An invalid handle value was provided. Either the handle does not exist at all, or refers to an object of an incorrect type.");
  210.    _ERROR_TYPE(VDP_STATUS_INVALID_POINTER,"An invalid pointer was provided. Typically, this means that a NULL pointer was provided for an 'output' parameter.");
  211.    _ERROR_TYPE(VDP_STATUS_INVALID_CHROMA_TYPE,"An invalid/unsupported VdpChromaType value was supplied.");
  212.    _ERROR_TYPE(VDP_STATUS_INVALID_Y_CB_CR_FORMAT,"An invalid/unsupported VdpYCbCrFormat value was supplied.");
  213.    _ERROR_TYPE(VDP_STATUS_INVALID_RGBA_FORMAT,"An invalid/unsupported VdpRGBAFormat value was supplied.");
  214.    _ERROR_TYPE(VDP_STATUS_INVALID_INDEXED_FORMAT,"An invalid/unsupported VdpIndexedFormat value was supplied.");
  215.    _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_STANDARD,"An invalid/unsupported VdpColorStandard value was supplied.");
  216.    _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,"An invalid/unsupported VdpColorTableFormat value was supplied.");
  217.    _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_FACTOR,"An invalid/unsupported VdpOutputSurfaceRenderBlendFactor value was supplied.");
  218.    _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_EQUATION,"An invalid/unsupported VdpOutputSurfaceRenderBlendEquation value was supplied.");
  219.    _ERROR_TYPE(VDP_STATUS_INVALID_FLAG,"An invalid/unsupported flag value/combination was supplied.");
  220.    _ERROR_TYPE(VDP_STATUS_INVALID_DECODER_PROFILE,"An invalid/unsupported VdpDecoderProfile value was supplied.");
  221.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,"An invalid/unsupported VdpVideoMixerFeature value was supplied.");
  222.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER,"An invalid/unsupported VdpVideoMixerParameter value was supplied.");
  223.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,"An invalid/unsupported VdpVideoMixerAttribute value was supplied.");
  224.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,"An invalid/unsupported VdpVideoMixerPictureStructure value was supplied.");
  225.    _ERROR_TYPE(VDP_STATUS_INVALID_FUNC_ID,"An invalid/unsupported VdpFuncId value was supplied.");
  226.    _ERROR_TYPE(VDP_STATUS_INVALID_SIZE,"The size of a supplied object does not match the object it is being used with.\
  227.      For example, a VdpVideoMixer is configured to process VdpVideoSurface objects of a specific size.\
  228.      If presented with a VdpVideoSurface of a different size, this error will be raised.");
  229.    _ERROR_TYPE(VDP_STATUS_INVALID_VALUE,"An invalid/unsupported value was supplied.\
  230.      This is a catch-all error code for values of type other than those with a specific error code.");
  231.    _ERROR_TYPE(VDP_STATUS_INVALID_STRUCT_VERSION,"An invalid/unsupported structure version was specified in a versioned structure. \
  232.      This implies that the implementation is older than the header file the application was built against.");
  233.    _ERROR_TYPE(VDP_STATUS_RESOURCES,"The system does not have enough resources to complete the requested operation at this time.");
  234.    _ERROR_TYPE(VDP_STATUS_HANDLE_DEVICE_MISMATCH,"The set of handles supplied are not all related to the same VdpDevice.When performing operations \
  235.      that operate on multiple surfaces, such as VdpOutputSurfaceRenderOutputSurface or VdpVideoMixerRender, \
  236.      all supplied surfaces must have been created within the context of the same VdpDevice object. \
  237.      This error is raised if they were not.");
  238.    _ERROR_TYPE(VDP_STATUS_ERROR,"A catch-all error, used when no other error code applies.");
  239.    default: return "Unknown Error";
  240.    }
  241. }
  242.  
  243. void
  244. vlVdpDefaultSamplerViewTemplate(struct pipe_sampler_view *templ, struct pipe_resource *res)
  245. {
  246.    const struct util_format_description *desc;
  247.  
  248.    memset(templ, 0, sizeof(*templ));
  249.    u_sampler_view_default_template(templ, res, res->format);
  250.  
  251.    desc = util_format_description(res->format);
  252.    if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_0)
  253.       templ->swizzle_r = PIPE_SWIZZLE_ONE;
  254.    if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0)
  255.       templ->swizzle_g = PIPE_SWIZZLE_ONE;
  256.    if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0)
  257.       templ->swizzle_b = PIPE_SWIZZLE_ONE;
  258.    if (desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_0)
  259.       templ->swizzle_a = PIPE_SWIZZLE_ONE;
  260. }
  261.  
  262. void
  263. vlVdpResolveDelayedRendering(vlVdpDevice *dev, struct pipe_surface *surface, struct u_rect *dirty_area)
  264. {
  265.    struct vl_compositor_state *cstate;
  266.    vlVdpOutputSurface *vlsurface;
  267.  
  268.    assert(dev);
  269.  
  270.    cstate = dev->delayed_rendering.cstate;
  271.    if (!cstate)
  272.       return;
  273.  
  274.    vlsurface = vlGetDataHTAB(dev->delayed_rendering.surface);
  275.    if (!vlsurface)
  276.       return;
  277.  
  278.    if (!surface) {
  279.       surface = vlsurface->surface;
  280.       dirty_area = &vlsurface->dirty_area;
  281.    }
  282.  
  283.    vl_compositor_render(cstate, &dev->compositor, surface, dirty_area, true);
  284.  
  285.    dev->delayed_rendering.surface = VDP_INVALID_HANDLE;
  286.    dev->delayed_rendering.cstate = NULL;
  287.  
  288.    /* test if we need to create a new sampler for the just filled texture */
  289.    if (surface->texture != vlsurface->sampler_view->texture) {
  290.       struct pipe_resource *res = surface->texture;
  291.       struct pipe_sampler_view sv_templ;
  292.  
  293.       vlVdpDefaultSamplerViewTemplate(&sv_templ, res);
  294.       pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
  295.       vlsurface->sampler_view = dev->context->create_sampler_view(dev->context, res, &sv_templ);
  296.    }
  297.  
  298.    return;
  299. }
  300.  
  301. void
  302. vlVdpSave4DelayedRendering(vlVdpDevice *dev, VdpOutputSurface surface, struct vl_compositor_state *cstate)
  303. {
  304.    assert(dev);
  305.  
  306.    vlVdpResolveDelayedRendering(dev, NULL, NULL);
  307.  
  308.    dev->delayed_rendering.surface = surface;
  309.    dev->delayed_rendering.cstate = cstate;
  310. }
  311.