| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/ozone/platform/dri/dri_buffer.h" | 5 #include "ui/ozone/platform/dri/dri_buffer.h" |
| 6 | 6 |
| 7 #include <errno.h> | |
| 8 #include <sys/mman.h> | |
| 9 #include <sys/types.h> | |
| 10 #include <xf86drm.h> | |
| 11 | |
| 12 #include "base/logging.h" | 7 #include "base/logging.h" |
| 13 #include "third_party/skia/include/core/SkCanvas.h" | |
| 14 #include "ui/ozone/platform/dri/dri_util.h" | |
| 15 #include "ui/ozone/platform/dri/dri_wrapper.h" | 8 #include "ui/ozone/platform/dri/dri_wrapper.h" |
| 16 | 9 |
| 17 namespace ui { | 10 namespace ui { |
| 18 | 11 |
| 19 namespace { | 12 namespace { |
| 20 | 13 |
| 21 // Modesetting cannot happen from a buffer with transparencies. Return the size | 14 // Modesetting cannot happen from a buffer with transparencies. Return the size |
| 22 // of a pixel without alpha. | 15 // of a pixel without alpha. |
| 23 uint8_t GetColorDepth(SkColorType type) { | 16 uint8_t GetColorDepth(SkColorType type) { |
| 24 switch (type) { | 17 switch (type) { |
| 25 case kUnknown_SkColorType: | 18 case kUnknown_SkColorType: |
| 26 case kAlpha_8_SkColorType: | 19 case kAlpha_8_SkColorType: |
| 27 return 0; | 20 return 0; |
| 28 case kIndex_8_SkColorType: | 21 case kIndex_8_SkColorType: |
| 29 return 8; | 22 return 8; |
| 30 case kRGB_565_SkColorType: | 23 case kRGB_565_SkColorType: |
| 31 return 16; | 24 return 16; |
| 32 case kARGB_4444_SkColorType: | 25 case kARGB_4444_SkColorType: |
| 33 return 12; | 26 return 12; |
| 34 case kN32_SkColorType: | 27 case kN32_SkColorType: |
| 35 return 24; | 28 return 24; |
| 36 default: | 29 default: |
| 37 NOTREACHED(); | 30 NOTREACHED(); |
| 38 return 0; | 31 return 0; |
| 39 } | 32 } |
| 40 } | 33 } |
| 41 | 34 |
| 42 void DestroyDumbBuffer(int fd, uint32_t handle) { | |
| 43 struct drm_mode_destroy_dumb destroy_request; | |
| 44 memset(&destroy_request, 0, sizeof(destroy_request)); | |
| 45 destroy_request.handle = handle; | |
| 46 drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request); | |
| 47 } | |
| 48 | |
| 49 bool CreateDumbBuffer(int fd, | |
| 50 const SkImageInfo& info, | |
| 51 uint32_t* handle, | |
| 52 uint32_t* stride) { | |
| 53 struct drm_mode_create_dumb request; | |
| 54 memset(&request, 0, sizeof(request)); | |
| 55 request.width = info.width(); | |
| 56 request.height = info.height(); | |
| 57 request.bpp = info.bytesPerPixel() << 3; | |
| 58 request.flags = 0; | |
| 59 | |
| 60 if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) { | |
| 61 VLOG(2) << "Cannot create dumb buffer (" << errno << ") " | |
| 62 << strerror(errno); | |
| 63 return false; | |
| 64 } | |
| 65 | |
| 66 // The driver may choose to align the last row as well. We don't care about | |
| 67 // the last alignment bits since they aren't used for display purposes, so | |
| 68 // just check that the expected size is <= to what the driver allocated. | |
| 69 DCHECK_LE(info.getSafeSize(request.pitch), request.size); | |
| 70 | |
| 71 *handle = request.handle; | |
| 72 *stride = request.pitch; | |
| 73 return true; | |
| 74 } | |
| 75 | |
| 76 } // namespace | 35 } // namespace |
| 77 | 36 |
| 78 DriBuffer::DriBuffer(DriWrapper* dri) | 37 DriBuffer::DriBuffer(DriWrapper* dri) |
| 79 : dri_(dri), handle_(0), framebuffer_(0) {} | 38 : dri_(dri), handle_(0), framebuffer_(0) {} |
| 80 | 39 |
| 81 DriBuffer::~DriBuffer() { | 40 DriBuffer::~DriBuffer() { |
| 82 if (!surface_) | 41 if (!surface_) |
| 83 return; | 42 return; |
| 84 | 43 |
| 85 if (framebuffer_) | 44 if (framebuffer_) |
| 86 dri_->RemoveFramebuffer(framebuffer_); | 45 dri_->RemoveFramebuffer(framebuffer_); |
| 87 | 46 |
| 88 SkImageInfo info; | 47 SkImageInfo info; |
| 89 void* pixels = const_cast<void*>(surface_->peekPixels(&info, NULL)); | 48 void* pixels = const_cast<void*>(surface_->peekPixels(&info, NULL)); |
| 90 if (!pixels) | 49 if (!pixels) |
| 91 return; | 50 return; |
| 92 | 51 |
| 93 munmap(pixels, info.getSafeSize(stride_)); | 52 dri_->DestroyDumbBuffer(info, handle_, stride_, pixels); |
| 94 DestroyDumbBuffer(dri_->get_fd(), handle_); | |
| 95 } | 53 } |
| 96 | 54 |
| 97 bool DriBuffer::Initialize(const SkImageInfo& info) { | 55 bool DriBuffer::Initialize(const SkImageInfo& info) { |
| 98 void* pixels = NULL; | 56 void* pixels = NULL; |
| 99 if (!CreateDumbBuffer(dri_->get_fd(), info, &handle_, &stride_)) { | 57 if (!dri_->CreateDumbBuffer(info, &handle_, &stride_, &pixels)) { |
| 100 VLOG(2) << "Cannot allocate drm dumb buffer"; | 58 VLOG(2) << "Cannot create drm dumb buffer"; |
| 101 return false; | 59 return false; |
| 102 } | 60 } |
| 103 | 61 |
| 104 if (!MapDumbBuffer(dri_->get_fd(), | |
| 105 handle_, | |
| 106 info.getSafeSize(stride_), | |
| 107 &pixels)) { | |
| 108 VLOG(2) << "Cannot map drm dumb buffer"; | |
| 109 DestroyDumbBuffer(dri_->get_fd(), handle_); | |
| 110 return false; | |
| 111 } | |
| 112 | |
| 113 if (!dri_->AddFramebuffer(info.width(), | 62 if (!dri_->AddFramebuffer(info.width(), |
| 114 info.height(), | 63 info.height(), |
| 115 GetColorDepth(info.colorType()), | 64 GetColorDepth(info.colorType()), |
| 116 info.bytesPerPixel() << 3, | 65 info.bytesPerPixel() << 3, |
| 117 stride_, | 66 stride_, |
| 118 handle_, | 67 handle_, |
| 119 &framebuffer_)) { | 68 &framebuffer_)) { |
| 120 VLOG(2) << "Failed to register framebuffer: " << strerror(errno); | 69 VLOG(2) << "Failed to register framebuffer: " << strerror(errno); |
| 121 return false; | 70 return false; |
| 122 } | 71 } |
| 123 | 72 |
| 124 surface_ = skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, stride_)); | 73 surface_ = skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, stride_)); |
| 125 if (!surface_) { | 74 if (!surface_) { |
| 126 VLOG(2) << "Cannot install Skia pixels for drm buffer"; | 75 VLOG(2) << "Cannot install Skia pixels for drm buffer"; |
| 127 return false; | 76 return false; |
| 128 } | 77 } |
| 129 | 78 |
| 130 return true; | 79 return true; |
| 131 } | 80 } |
| 132 | 81 |
| 133 } // namespace ui | 82 } // namespace ui |
| OLD | NEW |