Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindowsbackingstore.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qwindowswindow.h"
6#include "qwindowscontext.h"
7
8#include <QtGui/qwindow.h>
9#include <QtGui/qpainter.h>
10#include <QtGui/private/qwindowsnativeimage_p.h>
11#include <private/qhighdpiscaling_p.h>
12#include <private/qimage_p.h>
13
14#include <QtCore/qdebug.h>
15
17
26 m_alphaNeedsFill(false)
27{
28 qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
29}
30
32{
33 qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
34}
35
37{
38 Q_ASSERT(!m_image.isNull());
39 return &m_image->image();
40}
41
43 const QPoint &offset)
44{
46
47 const QRect br = region.boundingRect();
49 qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
51 Q_ASSERT(rw);
52
53 const bool hasAlpha = rw->format().hasAlpha();
54 const Qt::WindowFlags flags = window->flags();
55 if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
56 // Windows with alpha: Use blend function to update.
57 QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window);
58 QMargins frameMargins = rw->frameMargins();
59 QRect dirtyRect = br.translated(offset + QPoint(frameMargins.left(), frameMargins.top()));
60
61 SIZE size = {r.width(), r.height()};
62 POINT ptDst = {r.x(), r.y()};
63 POINT ptSrc = {0, 0};
64 BLENDFUNCTION blend = {AC_SRC_OVER, 0, BYTE(qRound(255.0 * rw->opacity())), AC_SRC_ALPHA};
65 RECT dirty = {dirtyRect.x(), dirtyRect.y(),
66 dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
67 UPDATELAYEREDWINDOWINFO info = {sizeof(info), nullptr, &ptDst, &size,
68 m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
69 const BOOL result = UpdateLayeredWindowIndirect(rw->handle(), &info);
70 if (!result)
71 qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d),"
72 " size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(),
73 r.width(), r.height(), dirtyRect.width(), dirtyRect.height(),
74 dirtyRect.x(), dirtyRect.y());
75 } else {
76 const HDC dc = rw->getDC();
77 if (!dc) {
78 qErrnoWarning("%s: GetDC failed", __FUNCTION__);
79 return;
80 }
81
82 if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
83 m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY)) {
84 const DWORD lastError = GetLastError(); // QTBUG-35926, QTBUG-29716: may fail after lock screen.
85 if (lastError != ERROR_SUCCESS && lastError != ERROR_INVALID_HANDLE)
86 qErrnoWarning(int(lastError), "%s: BitBlt failed", __FUNCTION__);
87 }
88 rw->releaseDC();
89 }
90
91 // Write image for debug purposes.
92 if (QWindowsContext::verbose > 2 && lcQpaBackingStore().isDebugEnabled()) {
93 static int n = 0;
94 const QString fileName = QString::fromLatin1("win%1_%2.png").
95 arg(rw->winId()).arg(n++);
96 m_image->image().save(fileName);
97 qCDebug(lcQpaBackingStore) << "Wrote " << m_image->image().size() << fileName;
98 }
99}
100
102{
103 if (m_image.isNull() || m_image->image().size() != size) {
104#ifndef QT_NO_DEBUG_OUTPUT
105 if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
106 qCDebug(lcQpaBackingStore)
107 << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
108 << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
109 }
110#endif
113
114 // The backingstore composition (enabling render-to-texture widgets)
115 // punches holes in the backingstores using the alpha channel. Hence
116 // the need for a true alpha format.
118 m_alphaNeedsFill = true;
119 else // upgrade but here we know app painting does not rely on alpha hence no need to fill
121
122 QWindowsNativeImage *oldwni = m_image.data();
123 auto *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
124
125 if (oldwni && !region.isEmpty()) {
126 const QImage &oldimg(oldwni->image());
127 QImage &newimg(newwni->image());
128 QRegion staticRegion(region);
129 staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height());
130 staticRegion &= QRect(0, 0, newimg.width(), newimg.height());
131 QPainter painter(&newimg);
133 for (const QRect &rect : staticRegion)
134 painter.drawImage(rect, oldimg, rect);
135 }
136
137 m_image.reset(newwni);
138 }
139}
140
141Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
142
143bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
144{
145 if (m_image.isNull() || m_image->image().isNull())
146 return false;
147
148 const QPoint offset(dx, dy);
149 const QRect rect = area.boundingRect();
151
152 return true;
153}
154
156{
158 qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
159
160 if (m_alphaNeedsFill) {
161 QPainter p(&m_image->image());
162 p.setCompositionMode(QPainter::CompositionMode_Source);
163 const QColor blank = Qt::transparent;
164 for (const QRect &r : region)
165 p.fillRect(r, blank);
166 }
167}
168
170{
171 if (!m_image.isNull())
172 return m_image->hdc();
173 return nullptr;
174}
175
177{
178 if (m_image.isNull()) {
179 qCWarning(lcQpaBackingStore) <<__FUNCTION__ << "Image is null.";
180 return QImage();
181 }
182 return m_image.data()->image();
183}
184
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtGui
Definition qimage.h:37
static QPixelFormat toPixelFormat(QImage::Format format) noexcept
Converts format into a QPixelFormat.
Definition qimage.cpp:6392
QSize size() const
Returns the size of the image, i.e.
bool save(const QString &fileName, const char *format=nullptr, int quality=-1) const
Saves the image to the file with the given fileName, using the given image file format and quality fa...
Definition qimage.cpp:3888
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition qimage.cpp:1222
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
\inmodule QtCore
Definition qmargins.h:24
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:106
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:109
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
Draws the rectangular portion source of the given image into the target rectangle in the paint device...
@ CompositionMode_Source
Definition qpainter.h:101
The QPlatformBackingStore class provides the drawing area for top-level windows.
QWindow * window() const
Returns a pointer to the top-level window associated with this surface.
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr QRect translated(int dx, int dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
Definition qrect.h:261
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
QRect boundingRect() const noexcept
Returns the bounding rectangle of this region.
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool hasAlpha() const
Returns true if the alpha buffer size is greater than zero.
\inmodule QtGui
Definition qwindow.h:63
Qt::WindowFlags flags
the window flags of the window
Definition qwindow.h:79
QSurfaceFormat format() const override
Returns the actual format of this window.
Definition qwindow.cpp:946
void beginPaint(const QRegion &) override
This function is called before painting onto the surface begins, with the region in which the paintin...
QPaintDevice * paintDevice() override
Implement this function to return the appropriate paint device.
bool scroll(const QRegion &area, int dx, int dy) override
Scrolls the given area dx pixels to the right and dy downward; both dx and dy may be negative.
QWindowsBackingStore(QWindow *window)
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override
Flushes the given region from the specified window.
void resize(const QSize &size, const QRegion &r) override
QImage toImage() const override
Implemented in subclasses to return the content of the backingstore as a QImage.
Windows Native image.
static QImage::Format systemFormat()
Raster or OpenGL Window.
static QWindowsWindow * windowsWindowOf(const QWindow *w)
static bool setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity)
rect
[4]
void qErrnoWarning(const char *msg,...)
T toNativePixels(const T &value, const C *context)
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
@ FramelessWindowHint
Definition qnamespace.h:225
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
static int area(const QSize &s)
Definition qicon.cpp:153
QImage::Format qt_maybeDataCompatibleAlphaVersion(QImage::Format format)
Definition qimage_p.h:478
#define qCWarning(category,...)
#define qCDebug(category,...)
#define SIZE(large, small, mini)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLbitfield flags
GLenum GLuint GLintptr offset
GLfloat n
GLint GLsizei GLsizei GLenum format
GLint void * img
Definition qopenglext.h:233
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
static bool hasAlpha(const QImage &image)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
QPainter painter(this)
[7]
aWidget window() -> setWindowTitle("New Window Title")
[2]
QHostInfo info
[0]