Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: ui/ozone/platform/drm/gpu/gbm_map_pixmap_intel.cc

Issue 1071273002: NotForReview: Implement zero/one-copy texture for ozone freon using Intel DRM Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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/ozone/platform/drm/gpu/gbm_map_pixmap_intel.h"
6
7 #include <libdrm/i915_drm.h>
8
9 #include "base/lazy_instance.h"
10 #include "base/numerics/safe_math.h"
11 #include "base/trace_event/trace_event.h"
12 #include "ui/ozone/platform/drm/gpu/gbm_device.h"
13 #include "ui/ozone/public/platform/drm_intel_buffer_manager.h"
14
15 namespace ui {
16
17 namespace {
18
19 int BytesPerPixel(SurfaceFactoryOzone::BufferFormat format) {
20 switch (format) {
21 case SurfaceFactoryOzone::BGRA_8888:
22 case SurfaceFactoryOzone::RGBX_8888:
23 return 4;
24 default:
25 NOTREACHED();
26 return 0;
27 }
28 }
29
30 unsigned long StrideInBytes(int width,
31 SurfaceFactoryOzone::BufferFormat format) {
32 base::CheckedNumeric<unsigned long> s = width;
33 switch (format) {
34 case SurfaceFactoryOzone::BGRA_8888:
35 case SurfaceFactoryOzone::RGBX_8888:
36 s *= BytesPerPixel(format);
37 DCHECK(s.IsValid());
38 return s.ValueOrDie();
39 default:
40 NOTREACHED();
41 return 0;
42 }
43 }
44
45 bool ShareToRenderProcess(int prime_fd, base::FileDescriptor* new_handle) {
46 const int new_fd = dup(prime_fd);
47 if (new_fd < 0) {
48 DPLOG(ERROR) << "dup() failed.";
49 return false;
50 }
51
52 *new_handle = base::FileDescriptor(new_fd, true);
53 return true;
54 }
55
56 base::LazyInstance<DrmIntelBufferManager>::Leaky g_buffer_manager =
57 LAZY_INSTANCE_INITIALIZER;
58
59 } // namespace
60
61 // static
62 scoped_refptr<GbmMapPixmapIntel> GbmMapPixmapIntel::CreatePixmap(
63 const scoped_refptr<GbmDevice>& gbm,
64 SurfaceFactoryOzone::BufferFormat format,
65 const gfx::Size& size,
66 gfx::GpuMemoryBufferHandle* handle) {
67 TRACE_EVENT2("drm", "GbmMapPixmapIntel::CreatePixmap", "device",
68 gbm->device_path().value(), "size", size.ToString());
69
70 scoped_refptr<GbmMapPixmapIntel> pixmap(new GbmMapPixmapIntel());
71 if (!pixmap->Initialize(gbm, format, size, handle))
72 return nullptr;
73
74 return pixmap;
75 }
76
77 GbmMapPixmapIntel::GbmMapPixmapIntel() : buffer_(nullptr), stride_(0) {
78 }
79
80 bool GbmMapPixmapIntel::Initialize(const scoped_refptr<GbmDevice>& gbm,
81 SurfaceFactoryOzone::BufferFormat format,
82 const gfx::Size& size,
83 gfx::GpuMemoryBufferHandle* handle) {
84 DCHECK(handle);
85 if (!g_buffer_manager.Pointer()->buffer_manager()) {
86 g_buffer_manager.Pointer()->Initialize(
87 base::FileDescriptor(gbm->get_fd(), false));
88 } else {
89 DCHECK(g_buffer_manager.Pointer()->device_fd() == gbm->get_fd());
90 }
91
92 unsigned long expected_stride = StrideInBytes(size.width(), format);
93 uint32_t tiling_mode = I915_TILING_NONE;
94 unsigned long stride = 0;
95 buffer_ = drm_intel_bo_alloc_tiled(
96 g_buffer_manager.Pointer()->buffer_manager(),
97 "chromium-gpu-memory-buffer", size.width(), size.height(),
98 BytesPerPixel(format), &tiling_mode, &stride, 0);
99 if (!buffer_) {
100 DLOG(ERROR) << "drm_intel_bo_alloc_tiled failed.";
101 return false;
102 }
103
104 // It's possible that StrideInBytes() doesn't match that of the driver.
105 // It's why it sends |stride| to render process.
106 if (stride != expected_stride) {
107 DLOG(WARNING) << "Unexpected stride: " << stride << " vs "
108 << expected_stride;
109 }
110 DCHECK(stride);
111 stride_ = stride;
112 handle->stride = stride_;
113
114 int prime_fd = -1;
115 drm_intel_bo_gem_export_to_prime(buffer_, &prime_fd);
116 if (prime_fd <= 0) {
117 DLOG(ERROR) << "Fail to export a drm buffer file descriptor";
118 return false;
119 }
120 prime_fd_.reset(prime_fd);
121 base::FileDescriptor dup_handle;
122 if (!ShareToRenderProcess(prime_fd_.get(), &dup_handle)) {
123 DLOG(ERROR) << "Fail to duplicate a drm buffer file descriptor";
124 return false;
125 }
126
127 base::FileDescriptor dup_device_handle;
128 if (!ShareToRenderProcess(gbm->get_fd(), &dup_device_handle)) {
129 base::ScopedFD fd(dup_handle.fd);
130 DLOG(ERROR) << "Fail to duplicate a drm file descriptor";
131 return false;
132 }
133
134 handle->handle = dup_handle;
135 // TODO(dshwang): pass |device_handle| only one time to each render process.
136 handle->device_handle = dup_device_handle;
137 return true;
138 }
139
140 GbmMapPixmapIntel::~GbmMapPixmapIntel() {
141 if (buffer_) {
142 // TODO(dshwang): It can fix glitch and crash bugs for Ozone GBM
143 // This is called after bound texture and bound EGLImage are deleted,
144 // but causes GPU Process crash in mesa with this log
145 // "drm intel crash: intel_do_flush_locked failed: Invalid argument"
146 // After drm_intel_bo_unreference() is called, sometime later, mesa causes
147 // crash, but gdb cannot catch stack trace. I guess crash happens in
148 // mesa internal thread.
149 // Surprisingly, glFinish in ResourceProvider::DeleteResourceInternal()
150 // fixes this issue also. see ResourceProvider
151 // drm_intel_bo_unreference(buffer_);
dshwang 2015/04/09 19:12:26 As comment said, this CL has glitch and crash bugs
152 buffer_ = nullptr;
153 }
154 }
155
156 void* GbmMapPixmapIntel::GetEGLClientBuffer() {
157 return nullptr;
158 }
159
160 int GbmMapPixmapIntel::GetDmaBufFd() {
161 return prime_fd_.get();
162 }
163
164 int GbmMapPixmapIntel::GetDmaBufPitch() {
165 return stride_;
166 }
167
168 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698