| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "ui/gfx/ozone/impl/dri_skbitmap.h" |  | 
| 6 |  | 
| 7 #include <errno.h> |  | 
| 8 #include <sys/mman.h> |  | 
| 9 #include <sys/types.h> |  | 
| 10 #include <xf86drm.h> |  | 
| 11 |  | 
| 12 #include "base/compiler_specific.h" |  | 
| 13 #include "base/logging.h" |  | 
| 14 #include "third_party/skia/include/core/SkPixelRef.h" |  | 
| 15 |  | 
| 16 namespace gfx { |  | 
| 17 |  | 
| 18 namespace { |  | 
| 19 |  | 
| 20 void DestroyDumbBuffer(int fd, uint32_t handle) { |  | 
| 21   struct drm_mode_destroy_dumb destroy_request; |  | 
| 22   destroy_request.handle = handle; |  | 
| 23   drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request); |  | 
| 24 } |  | 
| 25 |  | 
| 26 // Special DRM implementation of a SkPixelRef. The DRM allocator will create a |  | 
| 27 // SkPixelRef for the backing pixels. It will then associate the SkPixelRef with |  | 
| 28 // the SkBitmap. SkBitmap will access the allocated memory by locking the pixels |  | 
| 29 // in the SkPixelRef. |  | 
| 30 // At the end of its life the SkPixelRef is responsible for deallocating the |  | 
| 31 // pixel memory. |  | 
| 32 class DriSkPixelRef : public SkPixelRef { |  | 
| 33  public: |  | 
| 34   DriSkPixelRef(void* pixels, |  | 
| 35                 SkColorTable* color_table_, |  | 
| 36                 size_t size, |  | 
| 37                 int fd, |  | 
| 38                 uint32_t handle); |  | 
| 39   virtual ~DriSkPixelRef(); |  | 
| 40 |  | 
| 41   virtual void* onLockPixels(SkColorTable** ct) OVERRIDE; |  | 
| 42   virtual void onUnlockPixels() OVERRIDE; |  | 
| 43 |  | 
| 44   SK_DECLARE_UNFLATTENABLE_OBJECT() |  | 
| 45  private: |  | 
| 46   // Raw pointer to the pixel memory. |  | 
| 47   void* pixels_; |  | 
| 48 |  | 
| 49   // Optional color table associated with the pixel memory. |  | 
| 50   SkColorTable* color_table_; |  | 
| 51 |  | 
| 52   // Size of the allocated memory. |  | 
| 53   size_t size_; |  | 
| 54 |  | 
| 55   // File descriptor to the graphics card used to allocate/deallocate the |  | 
| 56   // memory. |  | 
| 57   int fd_; |  | 
| 58 |  | 
| 59   // Handle for the allocated memory. |  | 
| 60   uint32_t handle_; |  | 
| 61 |  | 
| 62   DISALLOW_COPY_AND_ASSIGN(DriSkPixelRef); |  | 
| 63 }; |  | 
| 64 |  | 
| 65 //////////////////////////////////////////////////////////////////////////////// |  | 
| 66 // DriSkPixelRef implementation |  | 
| 67 |  | 
| 68 DriSkPixelRef::DriSkPixelRef( |  | 
| 69     void* pixels, |  | 
| 70     SkColorTable* color_table, |  | 
| 71     size_t size, |  | 
| 72     int fd, |  | 
| 73     uint32_t handle) |  | 
| 74   : pixels_(pixels), |  | 
| 75     color_table_(color_table), |  | 
| 76     size_(size), |  | 
| 77     fd_(fd), |  | 
| 78     handle_(handle) { |  | 
| 79 } |  | 
| 80 |  | 
| 81 DriSkPixelRef::~DriSkPixelRef() { |  | 
| 82   munmap(pixels_, size_); |  | 
| 83   DestroyDumbBuffer(fd_, handle_); |  | 
| 84 } |  | 
| 85 |  | 
| 86 void* DriSkPixelRef::onLockPixels(SkColorTable** ct) { |  | 
| 87   *ct = color_table_; |  | 
| 88   return pixels_; |  | 
| 89 } |  | 
| 90 |  | 
| 91 void DriSkPixelRef::onUnlockPixels() { |  | 
| 92 } |  | 
| 93 |  | 
| 94 }  // namespace |  | 
| 95 |  | 
| 96 // Allocates pixel memory for a SkBitmap using DRM dumb buffers. |  | 
| 97 class DriAllocator : public SkBitmap::Allocator { |  | 
| 98  public: |  | 
| 99   DriAllocator(); |  | 
| 100 |  | 
| 101   virtual bool allocPixelRef(SkBitmap* bitmap, |  | 
| 102                              SkColorTable* color_table) OVERRIDE; |  | 
| 103 |  | 
| 104  private: |  | 
| 105   bool AllocatePixels(DriSkBitmap* bitmap, SkColorTable* color_table); |  | 
| 106 |  | 
| 107   DISALLOW_COPY_AND_ASSIGN(DriAllocator); |  | 
| 108 }; |  | 
| 109 |  | 
| 110 //////////////////////////////////////////////////////////////////////////////// |  | 
| 111 // DriAllocator implementation |  | 
| 112 |  | 
| 113 DriAllocator::DriAllocator() { |  | 
| 114 } |  | 
| 115 |  | 
| 116 bool DriAllocator::allocPixelRef(SkBitmap* bitmap, |  | 
| 117                                  SkColorTable* color_table) { |  | 
| 118   return AllocatePixels(static_cast<DriSkBitmap*>(bitmap), color_table); |  | 
| 119 } |  | 
| 120 |  | 
| 121 bool DriAllocator::AllocatePixels(DriSkBitmap* bitmap, |  | 
| 122                                   SkColorTable* color_table) { |  | 
| 123   struct drm_mode_create_dumb request; |  | 
| 124   request.width = bitmap->width(); |  | 
| 125   request.height = bitmap->height(); |  | 
| 126   request.bpp = bitmap->bytesPerPixel() << 3; |  | 
| 127   request.flags = 0; |  | 
| 128 |  | 
| 129   if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) { |  | 
| 130     DLOG(ERROR) << "Cannot create dumb buffer (" << errno << ") " |  | 
| 131                 << strerror(errno); |  | 
| 132     return false; |  | 
| 133   } |  | 
| 134 |  | 
| 135   CHECK(request.size == bitmap->getSize()); |  | 
| 136 |  | 
| 137   bitmap->set_handle(request.handle); |  | 
| 138 |  | 
| 139   struct drm_mode_map_dumb map_request; |  | 
| 140   map_request.handle = bitmap->get_handle(); |  | 
| 141   if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_MAP_DUMB, &map_request)) { |  | 
| 142     DLOG(ERROR) << "Cannot prepare dumb buffer for mapping (" << errno << ") " |  | 
| 143                 << strerror(errno); |  | 
| 144     DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle()); |  | 
| 145     return false; |  | 
| 146   } |  | 
| 147 |  | 
| 148   void* pixels = mmap(0, |  | 
| 149                       bitmap->getSize(), |  | 
| 150                       PROT_READ | PROT_WRITE, |  | 
| 151                       MAP_SHARED, |  | 
| 152                       bitmap->get_fd(), |  | 
| 153                       map_request.offset); |  | 
| 154   if (pixels == MAP_FAILED) { |  | 
| 155     DLOG(ERROR) << "Cannot mmap dumb buffer (" << errno << ") " |  | 
| 156                 << strerror(errno); |  | 
| 157     DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle()); |  | 
| 158     return false; |  | 
| 159   } |  | 
| 160 |  | 
| 161   bitmap->setPixelRef(new DriSkPixelRef( |  | 
| 162       pixels, |  | 
| 163       color_table, |  | 
| 164       bitmap->getSize(), |  | 
| 165       bitmap->get_fd(), |  | 
| 166       bitmap->get_handle()))->unref(); |  | 
| 167   bitmap->lockPixels(); |  | 
| 168 |  | 
| 169   return true; |  | 
| 170 } |  | 
| 171 |  | 
| 172 //////////////////////////////////////////////////////////////////////////////// |  | 
| 173 // DriSkBitmap implementation |  | 
| 174 |  | 
| 175 DriSkBitmap::DriSkBitmap(int fd) |  | 
| 176   : fd_(fd), |  | 
| 177     handle_(0), |  | 
| 178     framebuffer_(0) { |  | 
| 179 } |  | 
| 180 |  | 
| 181 DriSkBitmap::~DriSkBitmap() { |  | 
| 182 } |  | 
| 183 |  | 
| 184 bool DriSkBitmap::Initialize() { |  | 
| 185   DriAllocator drm_allocator; |  | 
| 186   return allocPixels(&drm_allocator, NULL); |  | 
| 187 } |  | 
| 188 |  | 
| 189 uint8_t DriSkBitmap::GetColorDepth() const { |  | 
| 190   switch (config()) { |  | 
| 191     case SkBitmap::kNo_Config: |  | 
| 192     case SkBitmap::kA1_Config: |  | 
| 193     case SkBitmap::kA8_Config: |  | 
| 194       return 0; |  | 
| 195     case SkBitmap::kIndex8_Config: |  | 
| 196       return 8; |  | 
| 197     case SkBitmap::kRGB_565_Config: |  | 
| 198       return 16; |  | 
| 199     case SkBitmap::kARGB_4444_Config: |  | 
| 200       return 12; |  | 
| 201     case SkBitmap::kARGB_8888_Config: |  | 
| 202       return 24; |  | 
| 203     default: |  | 
| 204       NOTREACHED(); |  | 
| 205       return 0; |  | 
| 206   } |  | 
| 207 } |  | 
| 208 |  | 
| 209 }  // namespace gfx |  | 
| OLD | NEW | 
|---|