225void QWaylandSurfacePrivate::surface_commit(Resource *)
227 Q_Q(QWaylandSurface);
230 QSize oldBufferSize = bufferSize;
231 QRectF oldSourceGeometry = sourceGeometry;
232 QSize oldDestinationSize = destinationSize;
233 bool oldHasContent = hasContent;
234 int oldBufferScale = bufferScale;
235 Qt::ScreenOrientation oldContentOrientation = contentOrientation;
238 if (pending.buffer.hasBuffer() || pending.newlyAttached)
239 bufferRef = pending.buffer;
240 contentOrientation = pending.contentOrientation;
241 bufferScale = pending.bufferScale;
242 bufferSize = bufferRef.size();
243 QSize surfaceSize = bufferSize / bufferScale;
244 sourceGeometry = !pending.sourceGeometry.isValid() ? QRect(QPoint(), surfaceSize) : pending.sourceGeometry;
245 destinationSize = pending.destinationSize.isEmpty() ? sourceGeometry.size().toSize() : pending.destinationSize;
246 QRect destinationRect(QPoint(), destinationSize);
248 damage = pending.surfaceDamage.intersected(destinationRect);
249 if (!pending.bufferDamage.isNull()) {
250 if (bufferScale == 1) {
251 damage |= pending.bufferDamage.intersected(destinationRect);
255 auto xform = [](
const QRect &r,
int scale) -> QRect {
257 QPoint{ r.x() / scale, r.y() / scale },
258 QPoint{ (r.right() + scale - 1) / scale, (r.bottom() + scale - 1) / scale }
262 for (
const QRect &r : pending.bufferDamage)
263 damage |= xform(r, bufferScale).intersected(destinationRect);
266 hasContent = bufferRef.hasContent();
267 frameCallbacks << pendingFrameCallbacks;
268 inputRegion = pending.inputRegion.intersected(destinationRect);
269 opaqueRegion = pending.opaqueRegion.intersected(destinationRect);
270 bool becameOpaque = opaqueRegion.boundingRect().contains(destinationRect);
271 if (becameOpaque != isOpaque) {
272 isOpaque = becameOpaque;
273 emit q->isOpaqueChanged();
276 QPoint offsetForNextFrame = pending.offset;
279 viewport->checkCommittedState();
282 pending.buffer = QWaylandBufferRef();
283 pending.offset = QPoint();
284 pending.newlyAttached =
false;
285 pending.bufferDamage = QRegion();
286 pending.surfaceDamage = QRegion();
287 pendingFrameCallbacks.clear();
290 if (
auto *buffer = bufferRef.buffer())
291 buffer->setCommitted(damage);
292 for (
auto *view : std::as_const(views))
293 view->bufferCommitted(bufferRef, damage);
299 emit q->damaged(damage);
301 if (oldContentOrientation != contentOrientation)
302 emit q->contentOrientationChanged();
304 if (oldBufferSize != bufferSize)
305 emit q->bufferSizeChanged();
307 if (oldBufferScale != bufferScale)
308 emit q->bufferScaleChanged();
310 if (oldDestinationSize != destinationSize)
311 emit q->destinationSizeChanged();
313 if (oldSourceGeometry != sourceGeometry)
314 emit q->sourceGeometryChanged();
316 if (oldHasContent != hasContent)
317 emit q->hasContentChanged();
319 if (!offsetForNextFrame.isNull())
320 emit q->offsetForNextFrame(offsetForNextFrame);
325void QWaylandSurfacePrivate::surface_set_buffer_transform(Resource *resource, int32_t orientation)
327 Q_Q(QWaylandSurface);
328 QScreen *screen =
nullptr;
329 if (
auto *view = q->primaryView()) {
330 if (
auto *output = view->output()) {
331 if (
auto *window = output->window())
332 screen = window->screen();
335 if (screen ==
nullptr)
336 screen = QGuiApplication::primaryScreen();
337 Qt::ScreenOrientation newContentOrientation = screen->primaryOrientation();
338 bool isPortrait = newContentOrientation == Qt::PortraitOrientation;
339 switch (orientation) {
340 case WL_OUTPUT_TRANSFORM_90:
341 newContentOrientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
343 case WL_OUTPUT_TRANSFORM_180:
344 newContentOrientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
346 case WL_OUTPUT_TRANSFORM_270:
347 newContentOrientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
349 case WL_OUTPUT_TRANSFORM_NORMAL:
350 newContentOrientation = Qt::PrimaryOrientation;
354 case WL_OUTPUT_TRANSFORM_FLIPPED:
355 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
356 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
357 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
361 wl_resource_post_error(resource->handle, WL_SURFACE_ERROR_INVALID_TRANSFORM,
362 "invalid buffer transform");
365 pending.contentOrientation = newContentOrientation;