Subversion Repositories Kolibri OS

Rev

Rev 7144 | 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_private *dev_priv = main_device->dev_private;
  65.     struct drm_i915_gem_object *obj = cursor->cobj;
  66.     u32      ifl;
  67.  
  68.     ifl = safe_cli();
  69.     list_del(&cursor->list);
  70.     safe_sti(ifl);
  71.  
  72.     if (!dev_priv->info.cursor_needs_physical)
  73.     {
  74.     i915_gem_object_ggtt_unpin(cursor->cobj);
  75.  
  76.     mutex_lock(&main_device->struct_mutex);
  77.     drm_gem_object_unreference(&obj->base);
  78.     mutex_unlock(&main_device->struct_mutex);
  79.     }
  80.     else
  81.     {
  82.         addr_t page = (addr_t)obj;
  83.         for(addr_t i = 0; i < (KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8)/4096; i+=4096)
  84.             FreePage(page+i);
  85.     }
  86.  
  87.     __DestroyObject(cursor);
  88. };
  89.  
  90. static int init_cursor(cursor_t *cursor)
  91. {
  92.     display_t *display = GetDisplay();
  93.     struct drm_device *dev = display->ddev;
  94.     struct drm_i915_private *dev_priv = dev->dev_private;
  95.     struct drm_i915_gem_object *obj;
  96.     uint32_t *bits;
  97.     uint32_t *src;
  98.     void     *mapped;
  99.  
  100.     int       i,j;
  101.     int       ret;
  102.  
  103.     mutex_lock(&dev->struct_mutex);
  104.  
  105.     if (dev_priv->info.cursor_needs_physical)
  106.     {
  107.         mapped = bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
  108.         if (unlikely(bits == NULL))
  109.         {
  110.             ret = -ENOMEM;
  111.             goto unlock;
  112.         };
  113.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  114.     }
  115.     else
  116.     {
  117.         obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
  118.         if (unlikely(obj == NULL))
  119.         {
  120.             ret = -ENOMEM;
  121.             goto unlock;
  122.         };
  123.  
  124.         ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
  125.         if (ret)
  126.             goto unref;
  127.  
  128.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  129.         if (ret)
  130.             goto unpin;
  131.  
  132. /* You don't need to worry about fragmentation issues.
  133.  * GTT space is continuous. I guarantee it.                           */
  134.  
  135.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  136.                     KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
  137.  
  138.         if (unlikely(bits == NULL))
  139.         {
  140.             ret = -ENOMEM;
  141.             goto unpin;
  142.         };
  143.         cursor->cobj = obj;
  144.     };
  145.  
  146.     mutex_unlock(&dev->struct_mutex);
  147.  
  148.     src = cursor->data;
  149.  
  150.     for(i = 0; i < 32; i++)
  151.     {
  152.         for(j = 0; j < 32; j++)
  153.             *bits++ = *src++;
  154.         for(j = 32; j < KMS_CURSOR_WIDTH; j++)
  155.             *bits++ = 0;
  156.     }
  157.     for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
  158.         *bits++ = 0;
  159.  
  160.     FreeKernelSpace(mapped);
  161.     KernelFree(cursor->data);
  162.     cursor->data = bits;
  163.     cursor->header.destroy = destroy_cursor;
  164.  
  165.     return 0;
  166.  
  167. unpin:
  168.     i915_gem_object_ggtt_unpin(obj);
  169. unref:
  170.     drm_gem_object_unreference(&obj->base);
  171. unlock:
  172.     mutex_unlock(&dev->struct_mutex);
  173.     return ret;
  174. }
  175.  
  176. void init_system_cursors(struct drm_device *dev)
  177. {
  178.     cursor_t  *cursor;
  179.     display_t *display;
  180.     u32      ifl;
  181.  
  182.     display = GetDisplay();
  183.  
  184.     mutex_init(&cursor_lock);
  185.  
  186.     ifl = safe_cli();
  187.     {
  188.         list_for_each_entry(cursor, &display->cursors, list)
  189.         {
  190.             init_cursor(cursor);
  191.         };
  192.  
  193.         display->restore_cursor(0,0);
  194.         display->init_cursor    = init_cursor;
  195.         display->select_cursor  = select_cursor_kms;
  196.         display->show_cursor    = NULL;
  197.         display->move_cursor    = move_cursor_kms;
  198.         display->restore_cursor = restore_cursor;
  199.         display->disable_mouse  = disable_mouse;
  200.         display->crtc->cursor_x = display->width/2;
  201.         display->crtc->cursor_y = display->height/2;
  202.  
  203.         select_cursor_kms(display->cursor);
  204.     };
  205.     safe_sti(ifl);
  206. }
  207.