1 // Copyright 2018 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/drm_framebuffer.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "ui/gfx/buffer_format_util.h"
11 #include "ui/gfx/linux/drm_util_linux.h"
12 #include "ui/gfx/linux/gbm_buffer.h"
13 #include "ui/ozone/platform/drm/common/drm_util.h"
14 #include "ui/ozone/platform/drm/gpu/drm_device.h"
15
16 namespace ui {
17
18 DrmFramebuffer::AddFramebufferParams::AddFramebufferParams() = default;
19 DrmFramebuffer::AddFramebufferParams::AddFramebufferParams(
20 const AddFramebufferParams& other) = default;
21 DrmFramebuffer::AddFramebufferParams::~AddFramebufferParams() = default;
22
23 // static
AddFramebuffer(scoped_refptr<DrmDevice> drm_device,DrmFramebuffer::AddFramebufferParams params)24 scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
25 scoped_refptr<DrmDevice> drm_device,
26 DrmFramebuffer::AddFramebufferParams params) {
27 uint64_t modifiers[4] = {0};
28 if (params.modifier != DRM_FORMAT_MOD_INVALID) {
29 for (size_t i = 0; i < params.num_planes; ++i)
30 modifiers[i] = params.modifier;
31 }
32
33 const auto fourcc_format = GetBufferFormatFromFourCCFormat(params.format);
34 const uint32_t opaque_format =
35 GetFourCCFormatForOpaqueFramebuffer(fourcc_format);
36 // Intel Display Controller won't support AR/B30 framebuffers, only XR/B30,
37 // but that doesn't matter because anyway those two bits of alpha are useless;
38 // use the opaque directly in this case.
39 const bool force_opaque = AlphaBitsForBufferFormat(fourcc_format) == 2;
40
41 const auto drm_format = force_opaque ? opaque_format : params.format;
42
43 uint32_t framebuffer_id = 0;
44 if (!drm_device->AddFramebuffer2(params.width, params.height, drm_format,
45 params.handles, params.strides,
46 params.offsets, modifiers, &framebuffer_id,
47 params.flags)) {
48 DPLOG(WARNING) << "AddFramebuffer2";
49 return nullptr;
50 }
51
52 uint32_t opaque_framebuffer_id = 0;
53 if (opaque_format != drm_format &&
54 !drm_device->AddFramebuffer2(params.width, params.height, opaque_format,
55 params.handles, params.strides,
56 params.offsets, modifiers,
57 &opaque_framebuffer_id, params.flags)) {
58 DPLOG(WARNING) << "AddFramebuffer2";
59 drm_device->RemoveFramebuffer(framebuffer_id);
60 return nullptr;
61 }
62
63 return base::MakeRefCounted<DrmFramebuffer>(
64 std::move(drm_device), framebuffer_id, drm_format, opaque_framebuffer_id,
65 opaque_format, params.modifier, params.preferred_modifiers,
66 gfx::Size(params.width, params.height));
67 }
68
69 // static
AddFramebuffer(scoped_refptr<DrmDevice> drm,const GbmBuffer * buffer,const gfx::Size & framebuffer_size,std::vector<uint64_t> preferred_modifiers)70 scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
71 scoped_refptr<DrmDevice> drm,
72 const GbmBuffer* buffer,
73 const gfx::Size& framebuffer_size,
74 std::vector<uint64_t> preferred_modifiers) {
75 DCHECK(gfx::Rect(buffer->GetSize()).Contains(gfx::Rect(framebuffer_size)));
76 AddFramebufferParams params;
77 params.format = buffer->GetFormat();
78 params.modifier = buffer->GetFormatModifier();
79 params.width = framebuffer_size.width();
80 params.height = framebuffer_size.height();
81 params.num_planes = buffer->GetNumPlanes();
82 params.preferred_modifiers = preferred_modifiers;
83 for (size_t i = 0; i < params.num_planes; ++i) {
84 params.handles[i] = buffer->GetPlaneHandle(i);
85 params.strides[i] = buffer->GetPlaneStride(i);
86 params.offsets[i] = buffer->GetPlaneOffset(i);
87 }
88
89 // AddFramebuffer2 only considers the modifiers if addfb_flags has
90 // DRM_MODE_FB_MODIFIERS set. We only set that when we've created
91 // a bo with modifiers, otherwise, we rely on the "no modifiers"
92 // behavior doing the right thing.
93 params.flags = 0;
94 if (drm->allow_addfb2_modifiers() &&
95 params.modifier != DRM_FORMAT_MOD_INVALID)
96 params.flags |= DRM_MODE_FB_MODIFIERS;
97
98 return AddFramebuffer(std::move(drm), params);
99 }
100
DrmFramebuffer(scoped_refptr<DrmDevice> drm_device,uint32_t framebuffer_id,uint32_t framebuffer_pixel_format,uint32_t opaque_framebuffer_id,uint32_t opaque_framebuffer_pixel_format,uint64_t format_modifier,std::vector<uint64_t> modifiers,const gfx::Size & size)101 DrmFramebuffer::DrmFramebuffer(scoped_refptr<DrmDevice> drm_device,
102 uint32_t framebuffer_id,
103 uint32_t framebuffer_pixel_format,
104 uint32_t opaque_framebuffer_id,
105 uint32_t opaque_framebuffer_pixel_format,
106 uint64_t format_modifier,
107 std::vector<uint64_t> modifiers,
108 const gfx::Size& size)
109 : drm_device_(std::move(drm_device)),
110 framebuffer_id_(framebuffer_id),
111 framebuffer_pixel_format_(framebuffer_pixel_format),
112 opaque_framebuffer_id_(opaque_framebuffer_id),
113 opaque_framebuffer_pixel_format_(opaque_framebuffer_pixel_format),
114 format_modifier_(format_modifier),
115 preferred_modifiers_(modifiers),
116 size_(size) {}
117
~DrmFramebuffer()118 DrmFramebuffer::~DrmFramebuffer() {
119 if (!drm_device_->RemoveFramebuffer(framebuffer_id_))
120 PLOG(WARNING) << "RemoveFramebuffer";
121 if (opaque_framebuffer_id_ &&
122 !drm_device_->RemoveFramebuffer(opaque_framebuffer_id_))
123 PLOG(WARNING) << "RemoveFramebuffer";
124 }
125
126 } // namespace ui
127