blob: 3ccdb78e9608ef801be58fb00d21e3a559d46487 [file] [log] [blame]
fei.dengf7a0cd32023-08-29 09:36:37 +00001/*
2 * Copyright (C) 2021 Amlogic Corporation.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16#include <sys/types.h>
17#include <sys/socket.h>
18#include <unistd.h>
19#include <fcntl.h>
20#include <errno.h>
21#include <sys/epoll.h>
22#include <string.h>
23#include <stdlib.h>
24#include <wayland-client.h>
25#include "xdg-shell-client-protocol.h"
26#include "viewporter-client-protocol.h"
27#include "linux-dmabuf-unstable-v1-client-protocol.h"
28#include "fullscreen-shell-unstable-v1-client-protocol.h"
29#include "wayland_display.h"
30#include "wayland_buffer.h"
31#include "Logger.h"
32#include "wayland_videoformat.h"
33#include "wayland_dma.h"
34#include "wayland_shm.h"
35#include "Utils.h"
fei.dengb9a1a572023-09-13 01:33:57 +000036#include "ErrorCode.h"
fei.dengf7a0cd32023-08-29 09:36:37 +000037
38#define TAG "rlib:wayland_buffer"
39
fei.dengb9a1a572023-09-13 01:33:57 +000040WaylandBuffer::WaylandBuffer(WaylandDisplay *display, int logCategory)
41 : mDisplay(display),
42 mLogCategory(logCategory)
fei.dengf7a0cd32023-08-29 09:36:37 +000043{
44 mRenderBuffer = NULL;
45 mWaylandWlWrap = NULL;
46 mUsedByCompositor = false;
47 mRedrawingPending = false;
48 mRealTime = -1;
49 mBufferFormat = VIDEO_FORMAT_UNKNOWN;
50 mFrameWidth = 0;
51 mFrameHeight = 0;
52}
53
54WaylandBuffer::~WaylandBuffer()
55{
56 /*if weston obtains the wl_buffer,we need
57 * notify user to release renderBuffer*/
58 if (mRenderBuffer) {
59 mDisplay->handleBufferReleaseCallback(this);
60 mRenderBuffer = NULL;
61 }
62 if (mWaylandWlWrap) {
63 delete mWaylandWlWrap;
64 mWaylandWlWrap = NULL;
65 }
66}
67
68void WaylandBuffer::bufferRelease (void *data, struct wl_buffer *wl_buffer)
69{
70 WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
fei.dengb9a1a572023-09-13 01:33:57 +000071 TRACE(waylandBuffer->mLogCategory,"--wl_buffer:%p,renderBuffer:%p",wl_buffer,waylandBuffer->mRenderBuffer);
fei.dengf7a0cd32023-08-29 09:36:37 +000072 waylandBuffer->mUsedByCompositor = false;
73 //sometimes this callback be called twice
74 //this cause double free,so check mRenderBuffer
75 if (waylandBuffer->mRenderBuffer) {
76 waylandBuffer->mDisplay->handleBufferReleaseCallback(waylandBuffer);
77 waylandBuffer->mRenderBuffer = NULL;
78 }
79}
80
81void WaylandBuffer::bufferdroped (void *data, struct wl_buffer *wl_buffer)
82{
83 WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
fei.dengb9a1a572023-09-13 01:33:57 +000084 WARNING(waylandBuffer->mLogCategory,"--droped wl_buffer:%p,renderBuffer:%p",wl_buffer,waylandBuffer->mRenderBuffer);
fei.dengf7a0cd32023-08-29 09:36:37 +000085 waylandBuffer->mUsedByCompositor = false;
86
87 if (waylandBuffer->mRenderBuffer) {
88 waylandBuffer->mDisplay->handleFrameDropedCallback(waylandBuffer);
89 waylandBuffer->mDisplay->handleBufferReleaseCallback(waylandBuffer);
90 waylandBuffer->mRenderBuffer = NULL;
91 }
92}
93
fei.deng47c0f482023-09-04 07:18:26 +000094//static const struct wl_buffer_listener buffer_listener = {
95// WaylandBuffer::bufferRelease,
96// WaylandBuffer::bufferdroped
97//};
98 static const struct wl_buffer_listener buffer_listener = {
99 WaylandBuffer::bufferRelease
100 };
fei.dengf7a0cd32023-08-29 09:36:37 +0000101
102/*if we commit buffers to weston too fast,it causes weston can't invoke this callback*/
103void WaylandBuffer::frameDisplayedCallback(void *data, struct wl_callback *callback, uint32_t time)
104{
105 WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
106 waylandBuffer->mDisplay->setRedrawingPending(false);
107 waylandBuffer->mLock.lock();
108 bool redrawing = waylandBuffer->mRedrawingPending;
109 waylandBuffer->mRedrawingPending = false;
110 waylandBuffer->mLock.unlock();
111 if (waylandBuffer->mRenderBuffer && redrawing) {
112 waylandBuffer->mDisplay->handleFrameDisplayedCallback(waylandBuffer);
113 }
114 wl_callback_destroy (callback);
115}
116
117static const struct wl_callback_listener frame_callback_listener = {
118 WaylandBuffer::frameDisplayedCallback
119};
120
121int WaylandBuffer::constructWlBuffer(RenderBuffer *buf)
122{
123 struct wl_buffer * wlbuffer = NULL;
124
125 mRenderBuffer = buf;
126 if (mWaylandWlWrap) {
fei.dengb9a1a572023-09-13 01:33:57 +0000127 return NO_ERROR;
fei.dengf7a0cd32023-08-29 09:36:37 +0000128 }
129
130 if (buf->flag & BUFFER_FLAG_DMA_BUFFER) {
fei.dengb9a1a572023-09-13 01:33:57 +0000131 WaylandDmaBuffer *waylanddma = new WaylandDmaBuffer(mDisplay, mLogCategory);
fei.dengf7a0cd32023-08-29 09:36:37 +0000132 wlbuffer = waylanddma->constructWlBuffer(&buf->dma, mBufferFormat);
133 if (!wlbuffer) {
134 delete waylanddma;
fei.dengb9a1a572023-09-13 01:33:57 +0000135 ERROR(mLogCategory,"create wl_buffer fail");
136 return ERROR_INVALID_OPERATION;
fei.dengf7a0cd32023-08-29 09:36:37 +0000137 }
138 mWaylandWlWrap = waylanddma;
139 mFrameWidth = buf->dma.width;
140 mFrameHeight = buf->dma.height;
141 }
142
143 /*register buffer release listen*/
144 wl_buffer_add_listener (wlbuffer, &buffer_listener, this);
145
fei.dengb9a1a572023-09-13 01:33:57 +0000146 return NO_ERROR;
fei.dengf7a0cd32023-08-29 09:36:37 +0000147}
148
149struct wl_buffer *WaylandBuffer::getWlBuffer()
150{
151 if (mWaylandWlWrap) {
152 return mWaylandWlWrap->getWlBuffer();
153 } else {
154 return NULL;
155 }
156}
157
158void WaylandBuffer::attach(struct wl_surface *surface)
159{
160 struct wl_callback *callback;
161 struct wl_buffer *wlbuffer = NULL;
162 if (mUsedByCompositor) {
fei.dengb9a1a572023-09-13 01:33:57 +0000163 DEBUG(mLogCategory,"buffer used by compositor");
fei.dengf7a0cd32023-08-29 09:36:37 +0000164 return;
165 }
166
167 //callback when this frame displayed
168 callback = wl_surface_frame (surface);
169 wl_callback_add_listener (callback, &frame_callback_listener, this);
170 mDisplay->setRedrawingPending(true);
171
172 wlbuffer = getWlBuffer();
173 if (wlbuffer) {
174 wl_surface_attach (surface, wlbuffer, 0, 0);
175 }
176
177 mUsedByCompositor = true;
178 mRedrawingPending = true;
179}