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.
5 #include "ui/gfx/ozone/dri/dri_skbitmap.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "third_party/skia/include/core/SkPixelRef.h"
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);
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
30 // At the end of its life the SkPixelRef is responsible for deallocating the
32 class DriSkPixelRef : public SkPixelRef {
34 DriSkPixelRef(const SkImageInfo& info,
36 SkColorTable* color_table_,
41 virtual ~DriSkPixelRef();
43 virtual bool onNewLockPixels(LockRec* rec) OVERRIDE;
44 virtual void onUnlockPixels() OVERRIDE;
46 SK_DECLARE_UNFLATTENABLE_OBJECT()
48 // Raw pointer to the pixel memory.
51 // Optional color table associated with the pixel memory.
52 SkColorTable* color_table_;
54 // Size of the allocated memory.
57 // Number of bytes between subsequent rows in the bitmap (stride).
60 // File descriptor to the graphics card used to allocate/deallocate the
64 // Handle for the allocated memory.
67 DISALLOW_COPY_AND_ASSIGN(DriSkPixelRef);
70 ////////////////////////////////////////////////////////////////////////////////
71 // DriSkPixelRef implementation
73 DriSkPixelRef::DriSkPixelRef(
74 const SkImageInfo& info,
76 SkColorTable* color_table,
83 color_table_(color_table),
85 row_bytes_(row_bytes),
90 DriSkPixelRef::~DriSkPixelRef() {
91 munmap(pixels_, size_);
92 DestroyDumbBuffer(fd_, handle_);
95 bool DriSkPixelRef::onNewLockPixels(LockRec* rec) {
96 rec->fPixels = pixels_;
97 rec->fRowBytes = row_bytes_;
98 rec->fColorTable = color_table_;
102 void DriSkPixelRef::onUnlockPixels() {
107 // Allocates pixel memory for a SkBitmap using DRM dumb buffers.
108 class DriAllocator : public SkBitmap::Allocator {
112 virtual bool allocPixelRef(SkBitmap* bitmap,
113 SkColorTable* color_table) OVERRIDE;
116 bool AllocatePixels(DriSkBitmap* bitmap, SkColorTable* color_table);
118 DISALLOW_COPY_AND_ASSIGN(DriAllocator);
121 ////////////////////////////////////////////////////////////////////////////////
122 // DriAllocator implementation
124 DriAllocator::DriAllocator() {
127 bool DriAllocator::allocPixelRef(SkBitmap* bitmap,
128 SkColorTable* color_table) {
129 return AllocatePixels(static_cast<DriSkBitmap*>(bitmap), color_table);
132 bool DriAllocator::AllocatePixels(DriSkBitmap* bitmap,
133 SkColorTable* color_table) {
134 struct drm_mode_create_dumb request;
135 request.width = bitmap->width();
136 request.height = bitmap->height();
137 request.bpp = bitmap->bytesPerPixel() << 3;
140 if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) {
141 DLOG(ERROR) << "Cannot create dumb buffer (" << errno << ") "
146 CHECK(request.size == bitmap->getSize());
148 bitmap->set_handle(request.handle);
150 struct drm_mode_map_dumb map_request;
151 map_request.handle = bitmap->get_handle();
152 if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_MAP_DUMB, &map_request)) {
153 DLOG(ERROR) << "Cannot prepare dumb buffer for mapping (" << errno << ") "
155 DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle());
159 void* pixels = mmap(0,
161 PROT_READ | PROT_WRITE,
165 if (pixels == MAP_FAILED) {
166 DLOG(ERROR) << "Cannot mmap dumb buffer (" << errno << ") "
168 DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle());
173 if (!bitmap->asImageInfo(&info)) {
174 DLOG(ERROR) << "Cannot get skia image info";
175 DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle());
179 bitmap->setPixelRef(new DriSkPixelRef(
186 bitmap->get_handle()))->unref();
187 bitmap->lockPixels();
192 ////////////////////////////////////////////////////////////////////////////////
193 // DriSkBitmap implementation
195 DriSkBitmap::DriSkBitmap(int fd)
201 DriSkBitmap::~DriSkBitmap() {
204 bool DriSkBitmap::Initialize() {
205 DriAllocator drm_allocator;
206 return allocPixels(&drm_allocator, NULL);
209 uint8_t DriSkBitmap::GetColorDepth() const {
211 case SkBitmap::kNo_Config:
212 case SkBitmap::kA8_Config:
214 case SkBitmap::kIndex8_Config:
216 case SkBitmap::kRGB_565_Config:
218 case SkBitmap::kARGB_4444_Config:
220 case SkBitmap::kARGB_8888_Config: