| Index: ui/gfx/ozone/impl/drm_skbitmap_ozone.cc
|
| diff --git a/ui/gfx/ozone/impl/drm_skbitmap_ozone.cc b/ui/gfx/ozone/impl/drm_skbitmap_ozone.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a2e76ebb5def2b35005f38387f01000c195d281b
|
| --- /dev/null
|
| +++ b/ui/gfx/ozone/impl/drm_skbitmap_ozone.cc
|
| @@ -0,0 +1,209 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/gfx/ozone/impl/drm_skbitmap_ozone.h"
|
| +
|
| +#include <errno.h>
|
| +#include <sys/mman.h>
|
| +#include <sys/types.h>
|
| +#include <xf86drm.h>
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "third_party/skia/include/core/SkPixelRef.h"
|
| +
|
| +namespace gfx {
|
| +
|
| +namespace {
|
| +
|
| +void DestroyDumbBuffer(int fd, uint32_t handle) {
|
| + struct drm_mode_destroy_dumb destroy_request;
|
| + destroy_request.handle = handle;
|
| + drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
|
| +}
|
| +
|
| +// Special DRM implementation of a SkPixelRef. The DRM allocator will create a
|
| +// SkPixelRef for the backing pixels. It will then associate the SkPixelRef with
|
| +// the SkBitmap. SkBitmap will access the allocated memory by locking the pixels
|
| +// in the SkPixelRef.
|
| +// At the end of its life the SkPixelRef is responsible for deallocating the
|
| +// pixel memory.
|
| +class DrmSkPixelRef : public SkPixelRef {
|
| + public:
|
| + DrmSkPixelRef(void* pixels,
|
| + SkColorTable* color_table_,
|
| + size_t size,
|
| + int fd,
|
| + uint32_t handle);
|
| + virtual ~DrmSkPixelRef();
|
| +
|
| + virtual void* onLockPixels(SkColorTable** ct) OVERRIDE;
|
| + virtual void onUnlockPixels() OVERRIDE;
|
| +
|
| + SK_DECLARE_UNFLATTENABLE_OBJECT()
|
| + private:
|
| + // Raw pointer to the pixel memory.
|
| + void* pixels_;
|
| +
|
| + // Optional color table associated with the pixel memory.
|
| + SkColorTable* color_table_;
|
| +
|
| + // Size of the allocated memory.
|
| + size_t size_;
|
| +
|
| + // File descriptor to the graphics card used to allocate/deallocate the
|
| + // memory.
|
| + int fd_;
|
| +
|
| + // Handle for the allocated memory.
|
| + uint32_t handle_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DrmSkPixelRef);
|
| +};
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DrmSkPixelRef implementation
|
| +
|
| +DrmSkPixelRef::DrmSkPixelRef(
|
| + void* pixels,
|
| + SkColorTable* color_table,
|
| + size_t size,
|
| + int fd,
|
| + uint32_t handle)
|
| + : pixels_(pixels),
|
| + color_table_(color_table),
|
| + size_(size),
|
| + fd_(fd),
|
| + handle_(handle) {
|
| +}
|
| +
|
| +DrmSkPixelRef::~DrmSkPixelRef() {
|
| + munmap(pixels_, size_);
|
| + DestroyDumbBuffer(fd_, handle_);
|
| +}
|
| +
|
| +void* DrmSkPixelRef::onLockPixels(SkColorTable** ct) {
|
| + *ct = color_table_;
|
| + return pixels_;
|
| +}
|
| +
|
| +void DrmSkPixelRef::onUnlockPixels() {
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Allocates pixel memory for a SkBitmap using DRM dumb buffers.
|
| +class DrmAllocator : public SkBitmap::Allocator {
|
| + public:
|
| + DrmAllocator();
|
| +
|
| + virtual bool allocPixelRef(SkBitmap* bitmap,
|
| + SkColorTable* color_table) OVERRIDE;
|
| +
|
| + private:
|
| + bool AllocatePixels(DrmSkBitmapOzone* bitmap, SkColorTable* color_table);
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DrmAllocator);
|
| +};
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DrmAllocator implementation
|
| +
|
| +DrmAllocator::DrmAllocator() {
|
| +}
|
| +
|
| +bool DrmAllocator::allocPixelRef(SkBitmap* bitmap,
|
| + SkColorTable* color_table) {
|
| + return AllocatePixels(static_cast<DrmSkBitmapOzone*>(bitmap), color_table);
|
| +}
|
| +
|
| +bool DrmAllocator::AllocatePixels(DrmSkBitmapOzone* bitmap,
|
| + SkColorTable* color_table) {
|
| + struct drm_mode_create_dumb request;
|
| + request.width = bitmap->width();
|
| + request.height = bitmap->height();
|
| + request.bpp = bitmap->bytesPerPixel() << 3;
|
| + request.flags = 0;
|
| +
|
| + if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) {
|
| + DLOG(ERROR) << "Cannot create dumb buffer (" << errno << ") "
|
| + << strerror(errno);
|
| + return false;
|
| + }
|
| +
|
| + CHECK(request.size == bitmap->getSize());
|
| +
|
| + bitmap->set_handle(request.handle);
|
| +
|
| + struct drm_mode_map_dumb map_request;
|
| + map_request.handle = bitmap->get_handle();
|
| + if (drmIoctl(bitmap->get_fd(), DRM_IOCTL_MODE_MAP_DUMB, &map_request)) {
|
| + DLOG(ERROR) << "Cannot prepare dumb buffer for mapping (" << errno << ") "
|
| + << strerror(errno);
|
| + DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle());
|
| + return false;
|
| + }
|
| +
|
| + void* pixels = mmap(0,
|
| + bitmap->getSize(),
|
| + PROT_READ | PROT_WRITE,
|
| + MAP_SHARED,
|
| + bitmap->get_fd(),
|
| + map_request.offset);
|
| + if (pixels == MAP_FAILED) {
|
| + DLOG(ERROR) << "Cannot mmap dumb buffer (" << errno << ") "
|
| + << strerror(errno);
|
| + DestroyDumbBuffer(bitmap->get_fd(), bitmap->get_handle());
|
| + return false;
|
| + }
|
| +
|
| + bitmap->setPixelRef(new DrmSkPixelRef(
|
| + pixels,
|
| + color_table,
|
| + bitmap->getSize(),
|
| + bitmap->get_fd(),
|
| + bitmap->get_handle()))->unref();
|
| + bitmap->lockPixels();
|
| +
|
| + return true;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DrmSkBitmapOzone implementation
|
| +
|
| +DrmSkBitmapOzone::DrmSkBitmapOzone(int fd)
|
| + : fd_(fd),
|
| + handle_(0),
|
| + framebuffer_(0) {
|
| +}
|
| +
|
| +DrmSkBitmapOzone::~DrmSkBitmapOzone() {
|
| +}
|
| +
|
| +bool DrmSkBitmapOzone::Initialize() {
|
| + DrmAllocator drm_allocator;
|
| + return allocPixels(&drm_allocator, NULL);
|
| +}
|
| +
|
| +uint8_t DrmSkBitmapOzone::GetColorDepth() const {
|
| + switch (config()) {
|
| + case SkBitmap::kNo_Config:
|
| + case SkBitmap::kA1_Config:
|
| + case SkBitmap::kA8_Config:
|
| + return 0;
|
| + case SkBitmap::kIndex8_Config:
|
| + return 8;
|
| + case SkBitmap::kRGB_565_Config:
|
| + return 16;
|
| + case SkBitmap::kARGB_4444_Config:
|
| + return 12;
|
| + case SkBitmap::kARGB_8888_Config:
|
| + return 24;
|
| + default:
|
| + NOTREACHED();
|
| + return 0;
|
| + }
|
| +}
|
| +
|
| +} // namespace gfx
|
|
|