Subversion Repositories Kolibri OS

Rev

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 VMWARE 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_format.h"
  33. #include "util/u_sampler.h"
  34.  
  35. #include "vdpau_private.h"
  36.  
  37. /**
  38.  * Create a VdpDevice object for use with X11.
  39.  */
  40. PUBLIC VdpStatus
  41. vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device,
  42.                           VdpGetProcAddress **get_proc_address)
  43. {
  44.    struct pipe_screen *pscreen;
  45.    struct pipe_resource *res, res_tmpl;
  46.    struct pipe_sampler_view sv_tmpl;
  47.    vlVdpDevice *dev = NULL;
  48.    VdpStatus ret;
  49.  
  50.    if (!(display && device && get_proc_address))
  51.       return VDP_STATUS_INVALID_POINTER;
  52.  
  53.    if (!vlCreateHTAB()) {
  54.       ret = VDP_STATUS_RESOURCES;
  55.       goto no_htab;
  56.    }
  57.  
  58.    dev = CALLOC(1, sizeof(vlVdpDevice));
  59.    if (!dev) {
  60.       ret = VDP_STATUS_RESOURCES;
  61.       goto no_dev;
  62.    }
  63.  
  64.    pipe_reference_init(&dev->reference, 1);
  65.  
  66.    dev->vscreen = vl_screen_create(display, screen);
  67.    if (!dev->vscreen) {
  68.       ret = VDP_STATUS_RESOURCES;
  69.       goto no_vscreen;
  70.    }
  71.  
  72.    pscreen = dev->vscreen->pscreen;
  73.    dev->context = pscreen->context_create(pscreen, dev->vscreen);
  74.    if (!dev->context) {
  75.       ret = VDP_STATUS_RESOURCES;
  76.       goto no_context;
  77.    }
  78.  
  79.    if (!pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) {
  80.       ret = VDP_STATUS_NO_IMPLEMENTATION;
  81.       goto no_context;
  82.    }
  83.  
  84.    memset(&res_tmpl, 0, sizeof(res_tmpl));
  85.  
  86.    res_tmpl.target = PIPE_TEXTURE_2D;
  87.    res_tmpl.format = PIPE_FORMAT_R8G8B8A8_UNORM;
  88.    res_tmpl.width0 = 1;
  89.    res_tmpl.height0 = 1;
  90.    res_tmpl.depth0 = 1;
  91.    res_tmpl.array_size = 1;
  92.    res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
  93.    res_tmpl.usage = PIPE_USAGE_DEFAULT;
  94.  
  95.    if (!CheckSurfaceParams(pscreen, &res_tmpl)) {
  96.       ret = VDP_STATUS_NO_IMPLEMENTATION;
  97.       goto no_resource;
  98.    }
  99.  
  100.    res = pscreen->resource_create(pscreen, &res_tmpl);
  101.    if (!res) {
  102.       ret = VDP_STATUS_RESOURCES;
  103.       goto no_resource;
  104.    }
  105.  
  106.    memset(&sv_tmpl, 0, sizeof(sv_tmpl));
  107.    u_sampler_view_default_template(&sv_tmpl, res, res->format);
  108.  
  109.    sv_tmpl.swizzle_r = PIPE_SWIZZLE_ONE;
  110.    sv_tmpl.swizzle_g = PIPE_SWIZZLE_ONE;
  111.    sv_tmpl.swizzle_b = PIPE_SWIZZLE_ONE;
  112.    sv_tmpl.swizzle_a = PIPE_SWIZZLE_ONE;
  113.  
  114.    dev->dummy_sv = dev->context->create_sampler_view(dev->context, res, &sv_tmpl);
  115.    pipe_resource_reference(&res, NULL);
  116.    if (!dev->dummy_sv) {
  117.       ret = VDP_STATUS_RESOURCES;
  118.       goto no_resource;
  119.    }
  120.  
  121.    *device = vlAddDataHTAB(dev);
  122.    if (*device == 0) {
  123.       ret = VDP_STATUS_ERROR;
  124.       goto no_handle;
  125.    }
  126.  
  127.    vl_compositor_init(&dev->compositor, dev->context);
  128.    pipe_mutex_init(dev->mutex);
  129.  
  130.    *get_proc_address = &vlVdpGetProcAddress;
  131.  
  132.    return VDP_STATUS_OK;
  133.  
  134. no_handle:
  135.    pipe_sampler_view_reference(&dev->dummy_sv, NULL);
  136. no_resource:
  137.    dev->context->destroy(dev->context);
  138. no_context:
  139.    vl_screen_destroy(dev->vscreen);
  140. no_vscreen:
  141.    FREE(dev);
  142. no_dev:
  143.    vlDestroyHTAB();
  144. no_htab:
  145.    return ret;
  146. }
  147.  
  148. /**
  149.  * Create a VdpPresentationQueueTarget for use with X11.
  150.  */
  151. VdpStatus
  152. vlVdpPresentationQueueTargetCreateX11(VdpDevice device, Drawable drawable,
  153.                                       VdpPresentationQueueTarget *target)
  154. {
  155.    vlVdpPresentationQueueTarget *pqt;
  156.    VdpStatus ret;
  157.  
  158.    if (!drawable)
  159.       return VDP_STATUS_INVALID_HANDLE;
  160.  
  161.    vlVdpDevice *dev = vlGetDataHTAB(device);
  162.    if (!dev)
  163.       return VDP_STATUS_INVALID_HANDLE;
  164.  
  165.    pqt = CALLOC(1, sizeof(vlVdpPresentationQueue));
  166.    if (!pqt)
  167.       return VDP_STATUS_RESOURCES;
  168.  
  169.    DeviceReference(&pqt->device, dev);
  170.    pqt->drawable = drawable;
  171.  
  172.    *target = vlAddDataHTAB(pqt);
  173.    if (*target == 0) {
  174.       ret = VDP_STATUS_ERROR;
  175.       goto no_handle;
  176.    }
  177.  
  178.    return VDP_STATUS_OK;
  179.  
  180. no_handle:
  181.    FREE(pqt);
  182.    return ret;
  183. }
  184.  
  185. /**
  186.  * Destroy a VdpPresentationQueueTarget.
  187.  */
  188. VdpStatus
  189. vlVdpPresentationQueueTargetDestroy(VdpPresentationQueueTarget presentation_queue_target)
  190. {
  191.    vlVdpPresentationQueueTarget *pqt;
  192.  
  193.    pqt = vlGetDataHTAB(presentation_queue_target);
  194.    if (!pqt)
  195.       return VDP_STATUS_INVALID_HANDLE;
  196.  
  197.    vlRemoveDataHTAB(presentation_queue_target);
  198.    DeviceReference(&pqt->device, NULL);
  199.    FREE(pqt);
  200.  
  201.    return VDP_STATUS_OK;
  202. }
  203.  
  204. /**
  205.  * Destroy a VdpDevice.
  206.  */
  207. VdpStatus
  208. vlVdpDeviceDestroy(VdpDevice device)
  209. {
  210.    vlVdpDevice *dev = vlGetDataHTAB(device);
  211.    if (!dev)
  212.       return VDP_STATUS_INVALID_HANDLE;
  213.  
  214.    vlRemoveDataHTAB(device);
  215.    DeviceReference(&dev, NULL);
  216.  
  217.    return VDP_STATUS_OK;
  218. }
  219.  
  220. /**
  221.  * Free a VdpDevice.
  222.  */
  223. void
  224. vlVdpDeviceFree(vlVdpDevice *dev)
  225. {
  226.    pipe_mutex_destroy(dev->mutex);
  227.    vl_compositor_cleanup(&dev->compositor);
  228.    pipe_sampler_view_reference(&dev->dummy_sv, NULL);
  229.    dev->context->destroy(dev->context);
  230.    vl_screen_destroy(dev->vscreen);
  231.    FREE(dev);
  232.    vlDestroyHTAB();
  233. }
  234.  
  235. /**
  236.  * Retrieve a VDPAU function pointer.
  237.  */
  238. VdpStatus
  239. vlVdpGetProcAddress(VdpDevice device, VdpFuncId function_id, void **function_pointer)
  240. {
  241.    vlVdpDevice *dev = vlGetDataHTAB(device);
  242.    if (!dev)
  243.       return VDP_STATUS_INVALID_HANDLE;
  244.  
  245.    if (!function_pointer)
  246.       return VDP_STATUS_INVALID_POINTER;
  247.  
  248.    if (!vlGetFuncFTAB(function_id, function_pointer))
  249.       return VDP_STATUS_INVALID_FUNC_ID;
  250.  
  251.    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Got proc address %p for id %d\n", *function_pointer, function_id);
  252.  
  253.    return VDP_STATUS_OK;
  254. }
  255.  
  256. #define _ERROR_TYPE(TYPE,STRING) case TYPE: return STRING;
  257.  
  258. /**
  259.  * Retrieve a string describing an error code.
  260.  */
  261. char const *
  262. vlVdpGetErrorString (VdpStatus status)
  263. {
  264.    switch (status) {
  265.    _ERROR_TYPE(VDP_STATUS_OK,"The operation completed successfully; no error.");
  266.    _ERROR_TYPE(VDP_STATUS_NO_IMPLEMENTATION,"No backend implementation could be loaded.");
  267.    _ERROR_TYPE(VDP_STATUS_DISPLAY_PREEMPTED,"The display was preempted, or a fatal error occurred. The application must re-initialize VDPAU.");
  268.    _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.");
  269.    _ERROR_TYPE(VDP_STATUS_INVALID_POINTER,"An invalid pointer was provided. Typically, this means that a NULL pointer was provided for an 'output' parameter.");
  270.    _ERROR_TYPE(VDP_STATUS_INVALID_CHROMA_TYPE,"An invalid/unsupported VdpChromaType value was supplied.");
  271.    _ERROR_TYPE(VDP_STATUS_INVALID_Y_CB_CR_FORMAT,"An invalid/unsupported VdpYCbCrFormat value was supplied.");
  272.    _ERROR_TYPE(VDP_STATUS_INVALID_RGBA_FORMAT,"An invalid/unsupported VdpRGBAFormat value was supplied.");
  273.    _ERROR_TYPE(VDP_STATUS_INVALID_INDEXED_FORMAT,"An invalid/unsupported VdpIndexedFormat value was supplied.");
  274.    _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_STANDARD,"An invalid/unsupported VdpColorStandard value was supplied.");
  275.    _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,"An invalid/unsupported VdpColorTableFormat value was supplied.");
  276.    _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_FACTOR,"An invalid/unsupported VdpOutputSurfaceRenderBlendFactor value was supplied.");
  277.    _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_EQUATION,"An invalid/unsupported VdpOutputSurfaceRenderBlendEquation value was supplied.");
  278.    _ERROR_TYPE(VDP_STATUS_INVALID_FLAG,"An invalid/unsupported flag value/combination was supplied.");
  279.    _ERROR_TYPE(VDP_STATUS_INVALID_DECODER_PROFILE,"An invalid/unsupported VdpDecoderProfile value was supplied.");
  280.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,"An invalid/unsupported VdpVideoMixerFeature value was supplied.");
  281.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER,"An invalid/unsupported VdpVideoMixerParameter value was supplied.");
  282.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,"An invalid/unsupported VdpVideoMixerAttribute value was supplied.");
  283.    _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,"An invalid/unsupported VdpVideoMixerPictureStructure value was supplied.");
  284.    _ERROR_TYPE(VDP_STATUS_INVALID_FUNC_ID,"An invalid/unsupported VdpFuncId value was supplied.");
  285.    _ERROR_TYPE(VDP_STATUS_INVALID_SIZE,"The size of a supplied object does not match the object it is being used with.\
  286.      For example, a VdpVideoMixer is configured to process VdpVideoSurface objects of a specific size.\
  287.      If presented with a VdpVideoSurface of a different size, this error will be raised.");
  288.    _ERROR_TYPE(VDP_STATUS_INVALID_VALUE,"An invalid/unsupported value was supplied.\
  289.      This is a catch-all error code for values of type other than those with a specific error code.");
  290.    _ERROR_TYPE(VDP_STATUS_INVALID_STRUCT_VERSION,"An invalid/unsupported structure version was specified in a versioned structure. \
  291.      This implies that the implementation is older than the header file the application was built against.");
  292.    _ERROR_TYPE(VDP_STATUS_RESOURCES,"The system does not have enough resources to complete the requested operation at this time.");
  293.    _ERROR_TYPE(VDP_STATUS_HANDLE_DEVICE_MISMATCH,"The set of handles supplied are not all related to the same VdpDevice.When performing operations \
  294.      that operate on multiple surfaces, such as VdpOutputSurfaceRenderOutputSurface or VdpVideoMixerRender, \
  295.      all supplied surfaces must have been created within the context of the same VdpDevice object. \
  296.      This error is raised if they were not.");
  297.    _ERROR_TYPE(VDP_STATUS_ERROR,"A catch-all error, used when no other error code applies.");
  298.    default: return "Unknown Error";
  299.    }
  300. }
  301.  
  302. void
  303. vlVdpDefaultSamplerViewTemplate(struct pipe_sampler_view *templ, struct pipe_resource *res)
  304. {
  305.    const struct util_format_description *desc;
  306.  
  307.    memset(templ, 0, sizeof(*templ));
  308.    u_sampler_view_default_template(templ, res, res->format);
  309.  
  310.    desc = util_format_description(res->format);
  311.    if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_0)
  312.       templ->swizzle_r = PIPE_SWIZZLE_ONE;
  313.    if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0)
  314.       templ->swizzle_g = PIPE_SWIZZLE_ONE;
  315.    if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0)
  316.       templ->swizzle_b = PIPE_SWIZZLE_ONE;
  317.    if (desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_0)
  318.       templ->swizzle_a = PIPE_SWIZZLE_ONE;
  319. }
  320.  
  321. void
  322. vlVdpResolveDelayedRendering(vlVdpDevice *dev, struct pipe_surface *surface, struct u_rect *dirty_area)
  323. {
  324.    struct vl_compositor_state *cstate;
  325.    vlVdpOutputSurface *vlsurface;
  326.  
  327.    assert(dev);
  328.  
  329.    cstate = dev->delayed_rendering.cstate;
  330.    if (!cstate)
  331.       return;
  332.  
  333.    vlsurface = vlGetDataHTAB(dev->delayed_rendering.surface);
  334.    if (!vlsurface)
  335.       return;
  336.  
  337.    if (!surface) {
  338.       surface = vlsurface->surface;
  339.       dirty_area = &vlsurface->dirty_area;
  340.    }
  341.  
  342.    vl_compositor_render(cstate, &dev->compositor, surface, dirty_area, true);
  343.  
  344.    dev->delayed_rendering.surface = VDP_INVALID_HANDLE;
  345.    dev->delayed_rendering.cstate = NULL;
  346.  
  347.    /* test if we need to create a new sampler for the just filled texture */
  348.    if (surface->texture != vlsurface->sampler_view->texture) {
  349.       struct pipe_resource *res = surface->texture;
  350.       struct pipe_sampler_view sv_templ;
  351.  
  352.       vlVdpDefaultSamplerViewTemplate(&sv_templ, res);
  353.       pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
  354.       vlsurface->sampler_view = dev->context->create_sampler_view(dev->context, res, &sv_templ);
  355.    }
  356.  
  357.    return;
  358. }
  359.  
  360. void
  361. vlVdpSave4DelayedRendering(vlVdpDevice *dev, VdpOutputSurface surface, struct vl_compositor_state *cstate)
  362. {
  363.    assert(dev);
  364.  
  365.    vlVdpResolveDelayedRendering(dev, NULL, NULL);
  366.  
  367.    dev->delayed_rendering.surface = surface;
  368.    dev->delayed_rendering.cstate = cstate;
  369. }
  370.