2 // Copyright (c) 2018 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include "pixeluploader.h"
19 #include "displayplanemanager.h"
20 #include "framebuffermanager.h"
23 #include "nativegpuresource.h"
24 #include "nativesurface.h"
25 #include "overlaylayer.h"
27 #include "resourcemanager.h"
29 #include <nativebufferhandler.h>
33 namespace hwcomposer {
35 #define DMA_BUF_SYNC_READ (1 << 0)
36 #define DMA_BUF_SYNC_WRITE (2 << 0)
37 #define DMA_BUF_SYNC_RW (DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE)
38 #define DMA_BUF_SYNC_START (0 << 2)
39 #define DMA_BUF_SYNC_END (1 << 2)
40 #define DMA_BUF_BASE 'b'
41 #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
47 PixelUploader::PixelUploader(const NativeBufferHandler* buffer_handler)
48 : HWCThread(-8, "PixelUploader"), buffer_handler_(buffer_handler) {
49 if (!cevent_.Initialize())
52 fd_chandler_.AddFd(cevent_.get_fd());
53 gpu_fd_ = buffer_handler_->GetFd();
56 PixelUploader::~PixelUploader() {
59 void PixelUploader::Initialize() {
61 ETRACE("Failed to initalize PixelUploader. %s", PRINTERROR());
65 void PixelUploader::RegisterPixelUploaderCallback(
66 std::shared_ptr<RawPixelUploadCallback> callback) {
70 void PixelUploader::UpdateLayerPixelData(
71 HWCNativeHandle handle, uint32_t original_width, uint32_t original_height,
72 uint32_t original_stride, void* callback_data, uint8_t* byteaddr,
73 PixelUploaderLayerCallback* layer_callback, HwcRect<int> surfaceDamage) {
74 pixel_data_lock_.lock();
75 pixel_data_.emplace_back();
76 PixelData& temp = pixel_data_.back();
77 temp.handle_ = handle;
78 temp.original_width_ = original_width;
79 temp.original_height_ = original_height;
80 temp.original_stride_ = original_stride;
81 temp.callback_data_ = callback_data;
82 temp.data_ = byteaddr;
83 temp.layer_callback_ = layer_callback;
84 temp.surfaceDamage = surfaceDamage;
87 tasks_ |= kRefreshRawPixelMap;
90 pixel_data_lock_.unlock();
94 void PixelUploader::Synchronize() {
99 void PixelUploader::ExitThread() {
101 std::vector<PixelData>().swap(pixel_data_);
104 void PixelUploader::HandleExit() {
107 void PixelUploader::HandleRoutine() {
108 HandleRawPixelUpdate();
111 void PixelUploader::Wait() {
112 if (fd_chandler_.Poll(-1) <= 0) {
113 ETRACE("Poll Failed in DisplayManager %s", PRINTERROR());
117 if (fd_chandler_.IsReady(cevent_.get_fd())) {
118 // If eventfd_ is ready, we need to wait on it (using read()) to clean
119 // the flag that says it is ready.
124 void PixelUploader::HandleRawPixelUpdate() {
126 tasks_ &= ~kRefreshRawPixelMap;
127 tasks_lock_.unlock();
129 pixel_data_lock_.lock();
131 if (pixel_data_.empty()) {
132 pixel_data_lock_.unlock();
137 std::vector<PixelData> texture_uploads;
138 for (auto& buffer : pixel_data_) {
139 texture_uploads.emplace_back(buffer);
142 std::vector<PixelData>().swap(pixel_data_);
143 pixel_data_lock_.unlock();
146 for (auto& buffer : texture_uploads) {
148 // Notify everyone that we are going to access this data.
149 callback_->Callback(true, buffer.callback_data_);
157 size_t size = buffer.handle_->meta_data_.height_ *
158 buffer.handle_->meta_data_.pitches_[0];
159 uint32_t prime_fd = buffer.handle_->meta_data_.prime_fds_[0];
161 uint32_t mapStride = buffer.original_stride_;
162 uint32_t bpp = mapStride / buffer.original_width_;
163 uint32_t x1 = buffer.surfaceDamage.left, y1 = buffer.surfaceDamage.top;
164 uint32_t x2 = buffer.surfaceDamage.right, y2 = buffer.surfaceDamage.bottom;
165 uint32_t startx = x1 * bpp;
166 uint32_t block_size = (x2 - x1) * bpp;
169 ptr = (uint8_t*)Map(buffer.handle_->meta_data_.prime_fds_[0], size);
173 // FIXME: Create texture and do texture upload.
175 for (int i = y1; i < y2; i++) {
176 memcpy(ptr + (i * buffer.handle_->meta_data_.pitches_[0] + startx),
177 buffer.data_ + (i * mapStride + startx), block_size);
182 Unmap(buffer.handle_->meta_data_.prime_fds_[0], ptr, size);
185 // Notify everyone that we are done accessing this data.
186 callback_->Callback(false, buffer.callback_data_);
189 if (buffer.layer_callback_) {
190 buffer.layer_callback_->UploadDone();
197 void* PixelUploader::Map(uint32_t prime_fd, size_t size) {
199 mmap(nullptr, size, (PROT_READ | PROT_WRITE), MAP_SHARED, prime_fd, 0);
200 if (addr == MAP_FAILED)
203 struct dma_buf_sync sync_start = {0};
204 sync_start.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
205 int rv = ioctl(prime_fd, DMA_BUF_IOCTL_SYNC, &sync_start);
207 ETRACE("DMA_BUF_IOCTL_SYNC failed during Map \n");
215 void PixelUploader::Unmap(uint32_t prime_fd, void* addr, size_t size) {
217 struct dma_buf_sync sync_start = {0};
218 sync_start.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
219 ioctl(prime_fd, DMA_BUF_IOCTL_SYNC, &sync_start);
224 } // namespace hwcomposer