Subversion Repositories Kolibri OS

Rev

Rev 6296 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <drm/drmP.h>
  2. #include "i915_drv.h"
  3. #include "intel_drv.h"
  4. #include <syscall.h>
  5. #include <display.h>
  6.  
  7. static struct mutex cursor_lock;
  8.  
  9. static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  10. {
  11.     struct drm_crtc *crtc = os_display->crtc;
  12.     struct drm_plane_state *cursor_state = crtc->cursor->state;
  13.  
  14.     x-= cursor->hot_x;
  15.     y-= cursor->hot_y;
  16.  
  17.     crtc->cursor_x = x;
  18.     crtc->cursor_y = y;
  19.  
  20.     cursor_state->crtc_x = x;
  21.     cursor_state->crtc_y = y;
  22.  
  23.     intel_crtc_update_cursor(crtc, cursor_state);
  24. };
  25.  
  26. static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  27. {
  28.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  29.     struct drm_crtc   *crtc = os_display->crtc;
  30.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  31.     struct drm_plane  *cursor_plane = crtc->cursor;
  32.     struct intel_plane_state *cursor_state = to_intel_plane_state(cursor_plane->state);
  33.  
  34.     cursor_t *old;
  35.  
  36.     old = os_display->cursor;
  37.  
  38.     mutex_lock(&cursor_lock);
  39.  
  40.     os_display->cursor = cursor;
  41.  
  42.     if (!dev_priv->info.cursor_needs_physical)
  43.        intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
  44.     else
  45.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  46.  
  47.     cursor_state->visible = 1;
  48.  
  49.     cursor_plane->state->crtc_w   = 64;
  50.     cursor_plane->state->crtc_h   = 64;
  51.     cursor_plane->state->rotation = 0;
  52.  
  53.     mutex_unlock(&cursor_lock);
  54.  
  55.     move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y);
  56.     return old;
  57. };
  58.  
  59. static void __stdcall restore_cursor(int x, int y){};
  60. static void disable_mouse(void){};
  61.  
  62. static void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  63. {
  64.     struct drm_i915_gem_object *obj = cursor->cobj;
  65.     list_del(&cursor->list);
  66.  
  67.     i915_gem_object_ggtt_unpin(cursor->cobj);
  68.  
  69.     mutex_lock(&main_device->struct_mutex);
  70.     drm_gem_object_unreference(&obj->base);
  71.     mutex_unlock(&main_device->struct_mutex);
  72.  
  73.     __DestroyObject(cursor);
  74. };
  75.  
  76. static int init_cursor(cursor_t *cursor)
  77. {
  78.     display_t *display = GetDisplay();
  79.     struct drm_device *dev = display->ddev;
  80.     struct drm_i915_private *dev_priv = dev->dev_private;
  81.     struct drm_i915_gem_object *obj;
  82.     uint32_t *bits;
  83.     uint32_t *src;
  84.     void     *mapped;
  85.  
  86.     int       i,j;
  87.     int       ret;
  88.  
  89.     mutex_lock(&dev->struct_mutex);
  90.  
  91.     if (dev_priv->info.cursor_needs_physical)
  92.     {
  93.         bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
  94.         if (unlikely(bits == NULL))
  95.         {
  96.             ret = -ENOMEM;
  97.             goto unlock;
  98.         };
  99.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  100.     }
  101.     else
  102.     {
  103.         obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
  104.         if (unlikely(obj == NULL))
  105.         {
  106.             ret = -ENOMEM;
  107.             goto unlock;
  108.         };
  109.  
  110.         ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
  111.         if (ret)
  112.             goto unref;
  113.  
  114.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  115.         if (ret)
  116.             goto unpin;
  117.  
  118. /* You don't need to worry about fragmentation issues.
  119.  * GTT space is continuous. I guarantee it.                           */
  120.  
  121.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  122.                     KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
  123.  
  124.         if (unlikely(bits == NULL))
  125.         {
  126.             ret = -ENOMEM;
  127.             goto unpin;
  128.         };
  129.         cursor->cobj = obj;
  130.     };
  131.  
  132.     mutex_unlock(&dev->struct_mutex);
  133.  
  134.     src = cursor->data;
  135.  
  136.     for(i = 0; i < 32; i++)
  137.     {
  138.         for(j = 0; j < 32; j++)
  139.             *bits++ = *src++;
  140.         for(j = 32; j < KMS_CURSOR_WIDTH; j++)
  141.             *bits++ = 0;
  142.     }
  143.     for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
  144.         *bits++ = 0;
  145.  
  146.     FreeKernelSpace(mapped);
  147.     KernelFree(cursor->data);
  148.     cursor->data = bits;
  149.     cursor->header.destroy = destroy_cursor;
  150.  
  151.     return 0;
  152.  
  153. unpin:
  154.     i915_gem_object_ggtt_unpin(obj);
  155. unref:
  156.     drm_gem_object_unreference(&obj->base);
  157. unlock:
  158.     mutex_unlock(&dev->struct_mutex);
  159.     return ret;
  160. }
  161.  
  162. void init_system_cursors(struct drm_device *dev)
  163. {
  164.     cursor_t  *cursor;
  165.     display_t *display;
  166.     u32      ifl;
  167.  
  168.     display = GetDisplay();
  169.  
  170.     mutex_init(&cursor_lock);
  171.  
  172.     ifl = safe_cli();
  173.     {
  174.         list_for_each_entry(cursor, &display->cursors, list)
  175.         {
  176.             init_cursor(cursor);
  177.         };
  178.  
  179.         display->restore_cursor(0,0);
  180.         display->init_cursor    = init_cursor;
  181.         display->select_cursor  = select_cursor_kms;
  182.         display->show_cursor    = NULL;
  183.         display->move_cursor    = move_cursor_kms;
  184.         display->restore_cursor = restore_cursor;
  185.         display->disable_mouse  = disable_mouse;
  186.         display->crtc->cursor_x = display->width/2;
  187.         display->crtc->cursor_y = display->height/2;
  188.  
  189.         select_cursor_kms(display->cursor);
  190.     };
  191.     safe_sti(ifl);
  192. }
  193.