Introduce an XRenderBackend similar to OpenGLBackend
An abstract backend is split out of SceneXRender which takes care of managing the render pictures and swapping them after a frame is rendered. Having this abstract allows to implement further backends for XRender which do not use the Overlay Window for compositing. To have it consistant the SceneXRender is now also created by a factory method.
This commit is contained in:
parent
2cf7a4bad3
commit
cfa1ead9e1
3 changed files with 271 additions and 97 deletions
|
@ -207,7 +207,7 @@ void Compositor::slotCompositingOptionsInitialized()
|
|||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
case XRenderCompositing:
|
||||
qDebug() << "Initializing XRender compositing";
|
||||
m_scene = new SceneXrender(Workspace::self());
|
||||
m_scene = SceneXrender::createScene();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
|
|
@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "effects.h"
|
||||
#include "overlaywindow.h"
|
||||
#include "paintredirector.h"
|
||||
#include "workspace.h"
|
||||
#include "xcbutils.h"
|
||||
#include "kwinxrenderutils.h"
|
||||
|
||||
|
@ -42,11 +43,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
//****************************************
|
||||
// SceneXrender
|
||||
//****************************************
|
||||
|
||||
xcb_render_picture_t SceneXrender::buffer = XCB_RENDER_PICTURE_NONE;
|
||||
ScreenPaintData SceneXrender::screen_paint;
|
||||
|
||||
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
|
||||
|
@ -89,92 +85,187 @@ static xcb_render_pictformat_t findFormatForVisual(xcb_visualid_t visual)
|
|||
return s_cache.value(visual, 0);
|
||||
}
|
||||
|
||||
SceneXrender::SceneXrender(Workspace* ws)
|
||||
: Scene(ws)
|
||||
, format(0)
|
||||
, front(XCB_RENDER_PICTURE_NONE)
|
||||
, m_overlayWindow(new OverlayWindow())
|
||||
, init_ok(false)
|
||||
//****************************************
|
||||
// XRenderBackend
|
||||
//****************************************
|
||||
XRenderBackend::XRenderBackend()
|
||||
: m_buffer(XCB_RENDER_PICTURE_NONE)
|
||||
, m_failed(false)
|
||||
{
|
||||
if (!Xcb::Extensions::self()->isRenderAvailable()) {
|
||||
qCritical() << "No XRender extension available";
|
||||
setFailed("No XRender extension available");
|
||||
return;
|
||||
}
|
||||
if (!Xcb::Extensions::self()->isFixesRegionAvailable()) {
|
||||
qCritical() << "No XFixes v3+ extension available";
|
||||
setFailed("No XFixes v3+ extension available");
|
||||
return;
|
||||
}
|
||||
initXRender(true);
|
||||
}
|
||||
|
||||
SceneXrender::~SceneXrender()
|
||||
XRenderBackend::~XRenderBackend()
|
||||
{
|
||||
if (!init_ok) {
|
||||
// TODO this probably needs to clean up whatever has been created until the failure
|
||||
m_overlayWindow->destroy();
|
||||
return;
|
||||
if (m_buffer) {
|
||||
xcb_render_free_picture(connection(), m_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
OverlayWindow* XRenderBackend::overlayWindow()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void XRenderBackend::showOverlay()
|
||||
{
|
||||
}
|
||||
|
||||
void XRenderBackend::setBuffer(xcb_render_picture_t buffer)
|
||||
{
|
||||
if (m_buffer != XCB_RENDER_PICTURE_NONE) {
|
||||
xcb_render_free_picture(connection(), m_buffer);
|
||||
}
|
||||
m_buffer = buffer;
|
||||
}
|
||||
|
||||
void XRenderBackend::setFailed(const QString& reason)
|
||||
{
|
||||
qCritical() << "Creating the XRender backend failed: " << reason;
|
||||
m_failed = true;
|
||||
}
|
||||
|
||||
void XRenderBackend::screenGeometryChanged(const QSize &size)
|
||||
{
|
||||
Q_UNUSED(size)
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// X11XRenderBackend
|
||||
//****************************************
|
||||
X11XRenderBackend::X11XRenderBackend()
|
||||
: XRenderBackend()
|
||||
, m_overlayWindow(new OverlayWindow())
|
||||
, m_front(XCB_RENDER_PICTURE_NONE)
|
||||
, m_format(0)
|
||||
{
|
||||
init(true);
|
||||
}
|
||||
|
||||
X11XRenderBackend::~X11XRenderBackend()
|
||||
{
|
||||
if (m_front) {
|
||||
xcb_render_free_picture(connection(), m_front);
|
||||
}
|
||||
SceneXrender::Window::cleanup();
|
||||
SceneXrender::EffectFrame::cleanup();
|
||||
xcb_render_free_picture(connection(), front);
|
||||
xcb_render_free_picture(connection(), buffer);
|
||||
buffer = XCB_RENDER_PICTURE_NONE;
|
||||
m_overlayWindow->destroy();
|
||||
delete m_overlayWindow;
|
||||
}
|
||||
|
||||
void SceneXrender::initXRender(bool createOverlay)
|
||||
OverlayWindow* X11XRenderBackend::overlayWindow()
|
||||
{
|
||||
init_ok = false;
|
||||
if (front != XCB_RENDER_PICTURE_NONE)
|
||||
xcb_render_free_picture(connection(), front);
|
||||
return m_overlayWindow.data();
|
||||
}
|
||||
|
||||
void X11XRenderBackend::showOverlay()
|
||||
{
|
||||
if (m_overlayWindow->window()) // show the window only after the first pass, since
|
||||
m_overlayWindow->show(); // that pass may take long
|
||||
}
|
||||
|
||||
void X11XRenderBackend::init(bool createOverlay)
|
||||
{
|
||||
if (m_front != XCB_RENDER_PICTURE_NONE)
|
||||
xcb_render_free_picture(connection(), m_front);
|
||||
bool haveOverlay = createOverlay ? m_overlayWindow->create() : (m_overlayWindow->window() != XCB_WINDOW_NONE);
|
||||
if (haveOverlay) {
|
||||
m_overlayWindow->setup(XCB_WINDOW_NONE);
|
||||
ScopedCPointer<xcb_get_window_attributes_reply_t> attribs(xcb_get_window_attributes_reply(connection(),
|
||||
xcb_get_window_attributes_unchecked(connection(), m_overlayWindow->window()), NULL));
|
||||
if (!attribs) {
|
||||
qCritical() << "Failed getting window attributes for overlay window";
|
||||
setFailed("Failed getting window attributes for overlay window");
|
||||
return;
|
||||
}
|
||||
format = findFormatForVisual(attribs->visual);
|
||||
if (format == 0) {
|
||||
qCritical() << "Failed to find XRender format for overlay window";
|
||||
m_format = findFormatForVisual(attribs->visual);
|
||||
if (m_format == 0) {
|
||||
setFailed("Failed to find XRender format for overlay window");
|
||||
return;
|
||||
}
|
||||
front = xcb_generate_id(connection());
|
||||
xcb_render_create_picture(connection(), front, m_overlayWindow->window(), format, 0, NULL);
|
||||
m_front = xcb_generate_id(connection());
|
||||
xcb_render_create_picture(connection(), m_front, m_overlayWindow->window(), m_format, 0, NULL);
|
||||
} else {
|
||||
// create XRender picture for the root window
|
||||
format = findFormatForVisual(defaultScreen()->root_visual);
|
||||
if (format == 0) {
|
||||
qCritical() << "Failed to find XRender format for root window";
|
||||
m_format = findFormatForVisual(defaultScreen()->root_visual);
|
||||
if (m_format == 0) {
|
||||
setFailed("Failed to find XRender format for root window");
|
||||
return; // error
|
||||
}
|
||||
front = xcb_generate_id(connection());
|
||||
m_front = xcb_generate_id(connection());
|
||||
const uint32_t values[] = {XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS};
|
||||
xcb_render_create_picture(connection(), front, rootWindow(), format, XCB_RENDER_CP_SUBWINDOW_MODE, values);
|
||||
xcb_render_create_picture(connection(), m_front, rootWindow(), m_format, XCB_RENDER_CP_SUBWINDOW_MODE, values);
|
||||
}
|
||||
createBuffer();
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
void X11XRenderBackend::createBuffer()
|
||||
{
|
||||
xcb_pixmap_t pixmap = xcb_generate_id(connection());
|
||||
xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displayWidth(), displayHeight());
|
||||
xcb_render_picture_t b = xcb_generate_id(connection());
|
||||
xcb_render_create_picture(connection(), b, pixmap, m_format, 0, NULL);
|
||||
xcb_free_pixmap(connection(), pixmap); // The picture owns the pixmap now
|
||||
setBuffer(b);
|
||||
}
|
||||
|
||||
void X11XRenderBackend::present(int mask, const QRegion &damage)
|
||||
{
|
||||
if (mask & Scene::PAINT_SCREEN_REGION) {
|
||||
// Use the damage region as the clip region for the root window
|
||||
XFixesRegion frontRegion(damage);
|
||||
xcb_xfixes_set_picture_clip_region(connection(), m_front, frontRegion, 0, 0);
|
||||
// copy composed buffer to the root window
|
||||
xcb_xfixes_set_picture_clip_region(connection(), buffer(), XCB_XFIXES_REGION_NONE, 0, 0);
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer(), XCB_RENDER_PICTURE_NONE,
|
||||
m_front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
xcb_xfixes_set_picture_clip_region(connection(), m_front, XCB_XFIXES_REGION_NONE, 0, 0);
|
||||
xcb_flush(connection());
|
||||
} else {
|
||||
// copy composed buffer to the root window
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer(), XCB_RENDER_PICTURE_NONE,
|
||||
m_front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
xcb_flush(connection());
|
||||
}
|
||||
}
|
||||
|
||||
void X11XRenderBackend::screenGeometryChanged(const QSize &size)
|
||||
{
|
||||
Q_UNUSED(size)
|
||||
init(false);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneXrender
|
||||
//****************************************
|
||||
SceneXrender* SceneXrender::createScene()
|
||||
{
|
||||
QScopedPointer<XRenderBackend> backend;
|
||||
backend.reset(new X11XRenderBackend);
|
||||
if (backend->isFailed()) {
|
||||
return NULL;
|
||||
}
|
||||
return new SceneXrender(backend.take());
|
||||
}
|
||||
|
||||
SceneXrender::SceneXrender(XRenderBackend *backend)
|
||||
: Scene(Workspace::self())
|
||||
, m_backend(backend)
|
||||
{
|
||||
}
|
||||
|
||||
SceneXrender::~SceneXrender()
|
||||
{
|
||||
SceneXrender::Window::cleanup();
|
||||
SceneXrender::EffectFrame::cleanup();
|
||||
}
|
||||
|
||||
bool SceneXrender::initFailed() const
|
||||
{
|
||||
return !init_ok;
|
||||
}
|
||||
|
||||
// Create the compositing buffer. The root window is not double-buffered,
|
||||
// so it is done manually using this buffer,
|
||||
void SceneXrender::createBuffer()
|
||||
{
|
||||
if (buffer != XCB_RENDER_PICTURE_NONE)
|
||||
xcb_render_free_picture(connection(), buffer);
|
||||
xcb_pixmap_t pixmap = xcb_generate_id(connection());
|
||||
xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displayWidth(), displayHeight());
|
||||
buffer = xcb_generate_id(connection());
|
||||
xcb_render_create_picture(connection(), buffer, pixmap, format, 0, NULL);
|
||||
xcb_free_pixmap(connection(), pixmap); // The picture owns the pixmap now
|
||||
return false;
|
||||
}
|
||||
|
||||
// the entry point for painting
|
||||
|
@ -189,36 +280,15 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels)
|
|||
QRegion updateRegion, validRegion;
|
||||
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
||||
|
||||
if (m_overlayWindow->window()) // show the window only after the first pass, since
|
||||
m_overlayWindow->show(); // that pass may take long
|
||||
m_backend->showOverlay();
|
||||
|
||||
present(mask, updateRegion);
|
||||
m_backend->present(mask, updateRegion);
|
||||
// do cleanup
|
||||
clearStackingOrder();
|
||||
|
||||
return renderTimer.nsecsElapsed();
|
||||
}
|
||||
|
||||
void SceneXrender::present(int mask, QRegion damage)
|
||||
{
|
||||
if (mask & PAINT_SCREEN_REGION) {
|
||||
// Use the damage region as the clip region for the root window
|
||||
XFixesRegion frontRegion(damage);
|
||||
xcb_xfixes_set_picture_clip_region(connection(), front, frontRegion, 0, 0);
|
||||
// copy composed buffer to the root window
|
||||
xcb_xfixes_set_picture_clip_region(connection(), buffer, XCB_XFIXES_REGION_NONE, 0, 0);
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer, XCB_RENDER_PICTURE_NONE,
|
||||
front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
xcb_xfixes_set_picture_clip_region(connection(), front, XCB_XFIXES_REGION_NONE, 0, 0);
|
||||
xcb_flush(connection());
|
||||
} else {
|
||||
// copy composed buffer to the root window
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer, XCB_RENDER_PICTURE_NONE,
|
||||
front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
xcb_flush(connection());
|
||||
}
|
||||
}
|
||||
|
||||
void SceneXrender::paintGenericScreen(int mask, ScreenPaintData data)
|
||||
{
|
||||
screen_paint = data; // save, transformations will be done when painting windows
|
||||
|
@ -237,12 +307,12 @@ void SceneXrender::paintBackground(QRegion region)
|
|||
{
|
||||
xcb_render_color_t col = { 0, 0, 0, 0xffff }; // black
|
||||
const QVector<xcb_rectangle_t> &rects = Xcb::regionToRects(region);
|
||||
xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, buffer, col, rects.count(), rects.data());
|
||||
xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, bufferPicture(), col, rects.count(), rects.data());
|
||||
}
|
||||
|
||||
Scene::Window *SceneXrender::createWindow(Toplevel *toplevel)
|
||||
{
|
||||
return new Window(toplevel);
|
||||
return new Window(toplevel, this);
|
||||
}
|
||||
|
||||
Scene::EffectFrame *SceneXrender::createEffectFrame(EffectFrameImpl *frame)
|
||||
|
@ -262,8 +332,9 @@ Shadow *SceneXrender::createShadow(Toplevel *toplevel)
|
|||
XRenderPicture *SceneXrender::Window::s_tempPicture = 0;
|
||||
QRect SceneXrender::Window::temp_visibleRect;
|
||||
|
||||
SceneXrender::Window::Window(Toplevel* c)
|
||||
SceneXrender::Window::Window(Toplevel* c, SceneXrender *scene)
|
||||
: Scene::Window(c)
|
||||
, m_scene(scene)
|
||||
, format(findFormatForVisual(c->visual()->visualid))
|
||||
, alpha_cached_opacity(0.0)
|
||||
{
|
||||
|
@ -464,7 +535,7 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat
|
|||
const bool blitInTempPixmap = xRenderOffscreen() || (data.crossFadeProgress() < 1.0 && !opaque) ||
|
||||
(scaled && (wantShadow || (client && !client->noBorder()) || (deleted && !deleted->noBorder())));
|
||||
|
||||
xcb_render_picture_t renderTarget = buffer;
|
||||
xcb_render_picture_t renderTarget = m_scene->bufferPicture();
|
||||
if (blitInTempPixmap) {
|
||||
if (scene_xRenderOffscreenTarget()) {
|
||||
temp_visibleRect = toplevel->visibleRect().translated(-toplevel->pos());
|
||||
|
@ -675,7 +746,7 @@ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, _PART_, decorationAl
|
|||
xcb_render_set_picture_transform(connection(), *s_tempPicture, xform);
|
||||
setPictureFilter(*s_tempPicture, filter);
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, *s_tempPicture,
|
||||
XCB_RENDER_PICTURE_NONE, buffer,
|
||||
XCB_RENDER_PICTURE_NONE, m_scene->bufferPicture(),
|
||||
0, 0, 0, 0, r.x(), r.y(), r.width(), r.height());
|
||||
xcb_render_set_picture_transform(connection(), *s_tempPicture, identity);
|
||||
}
|
||||
|
@ -715,7 +786,7 @@ WindowPixmap* SceneXrender::Window::createWindowPixmap()
|
|||
void SceneXrender::screenGeometryChanged(const QSize &size)
|
||||
{
|
||||
Scene::screenGeometryChanged(size);
|
||||
initXRender(false);
|
||||
m_backend->screenGeometryChanged(size);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
|
|
127
scene_xrender.h
127
scene_xrender.h
|
@ -29,6 +29,113 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Backend for the SceneXRender to hold the compositing buffer and take care of buffer
|
||||
* swapping.
|
||||
*
|
||||
* This class is intended as a small abstraction to support multiple compositing backends in the
|
||||
* SceneXRender.
|
||||
*
|
||||
*/
|
||||
class XRenderBackend
|
||||
{
|
||||
public:
|
||||
virtual ~XRenderBackend();
|
||||
virtual void present(int mask, const QRegion &damage) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the OverlayWindow used by the backend.
|
||||
*
|
||||
* A backend does not have to use an OverlayWindow, this is mostly for the X world.
|
||||
* In case the backend does not use an OverlayWindow it is allowed to return @c null.
|
||||
* It's the task of the caller to check whether it is @c null.
|
||||
*
|
||||
* @return :OverlayWindow*
|
||||
**/
|
||||
virtual OverlayWindow *overlayWindow();
|
||||
/**
|
||||
* @brief Shows the Overlay Window
|
||||
*
|
||||
* Default implementation does nothing.
|
||||
*/
|
||||
virtual void showOverlay();
|
||||
/**
|
||||
* @brief React on screen geometry changes.
|
||||
*
|
||||
* Default implementation does nothing. Override if specific functionality is required.
|
||||
*
|
||||
* @param size The new screen size
|
||||
*/
|
||||
virtual void screenGeometryChanged(const QSize &size);
|
||||
/**
|
||||
* @brief The compositing buffer hold by this backend.
|
||||
*
|
||||
* The Scene composites the new frame into this buffer.
|
||||
*
|
||||
* @return xcb_render_picture_t
|
||||
*/
|
||||
xcb_render_picture_t buffer() const {
|
||||
return m_buffer;
|
||||
}
|
||||
/**
|
||||
* @brief Whether the creation of the Backend failed.
|
||||
*
|
||||
* The SceneXRender should test whether the Backend got constructed correctly. If this method
|
||||
* returns @c true, the SceneXRender should not try to start the rendering.
|
||||
*
|
||||
* @return bool @c true if the creation of the Backend failed, @c false otherwise.
|
||||
**/
|
||||
bool isFailed() const {
|
||||
return m_failed;
|
||||
}
|
||||
|
||||
protected:
|
||||
XRenderBackend();
|
||||
/**
|
||||
* @brief A subclass needs to call this method once it created the compositing back buffer.
|
||||
*
|
||||
* @param buffer The buffer to use for compositing
|
||||
* @return void
|
||||
*/
|
||||
void setBuffer(xcb_render_picture_t buffer);
|
||||
/**
|
||||
* @brief Sets the backend initialization to failed.
|
||||
*
|
||||
* This method should be called by the concrete subclass in case the initialization failed.
|
||||
* The given @p reason is logged as a warning.
|
||||
*
|
||||
* @param reason The reason why the initialization failed.
|
||||
**/
|
||||
void setFailed(const QString &reason);
|
||||
|
||||
private:
|
||||
// Create the compositing buffer. The root window is not double-buffered,
|
||||
// so it is done manually using this buffer,
|
||||
xcb_render_picture_t m_buffer;
|
||||
bool m_failed;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief XRenderBackend using an X11 Overlay Window as compositing target.
|
||||
*
|
||||
*/
|
||||
class X11XRenderBackend : public XRenderBackend
|
||||
{
|
||||
public:
|
||||
X11XRenderBackend();
|
||||
~X11XRenderBackend();
|
||||
|
||||
virtual void present(int mask, const QRegion &damage);
|
||||
virtual OverlayWindow* overlayWindow();
|
||||
virtual void showOverlay();
|
||||
virtual void screenGeometryChanged(const QSize &size);
|
||||
private:
|
||||
void init(bool createOverlay);
|
||||
void createBuffer();
|
||||
QScopedPointer<OverlayWindow> m_overlayWindow;
|
||||
xcb_render_picture_t m_front;
|
||||
xcb_render_pictformat_t m_format;
|
||||
};
|
||||
|
||||
class SceneXrender
|
||||
: public Scene
|
||||
|
@ -36,7 +143,6 @@ class SceneXrender
|
|||
Q_OBJECT
|
||||
public:
|
||||
class EffectFrame;
|
||||
explicit SceneXrender(Workspace* ws);
|
||||
virtual ~SceneXrender();
|
||||
virtual bool initFailed() const;
|
||||
virtual CompositingType compositingType() const {
|
||||
|
@ -48,31 +154,27 @@ public:
|
|||
virtual void screenGeometryChanged(const QSize &size);
|
||||
xcb_render_picture_t bufferPicture();
|
||||
virtual OverlayWindow *overlayWindow() {
|
||||
return m_overlayWindow;
|
||||
return m_backend->overlayWindow();
|
||||
}
|
||||
|
||||
static SceneXrender *createScene();
|
||||
protected:
|
||||
virtual Scene::Window *createWindow(Toplevel *toplevel);
|
||||
virtual void paintBackground(QRegion region);
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data);
|
||||
private:
|
||||
void createBuffer();
|
||||
void present(int mask, QRegion damage);
|
||||
void initXRender(bool createOverlay);
|
||||
xcb_render_pictformat_t format;
|
||||
xcb_render_picture_t front;
|
||||
static xcb_render_picture_t buffer;
|
||||
explicit SceneXrender(XRenderBackend *backend);
|
||||
static ScreenPaintData screen_paint;
|
||||
class Window;
|
||||
OverlayWindow* m_overlayWindow;
|
||||
bool init_ok;
|
||||
QScopedPointer<XRenderBackend> m_backend;
|
||||
};
|
||||
|
||||
class SceneXrender::Window
|
||||
: public Scene::Window
|
||||
{
|
||||
public:
|
||||
Window(Toplevel* c);
|
||||
Window(Toplevel* c, SceneXrender *scene);
|
||||
virtual ~Window();
|
||||
virtual void performPaint(int mask, QRegion region, WindowPaintData data);
|
||||
QRegion transformedShape() const;
|
||||
|
@ -85,6 +187,7 @@ private:
|
|||
QPoint mapToScreen(int mask, const WindowPaintData &data, const QPoint &point) const;
|
||||
void prepareTempPixmap();
|
||||
void setPictureFilter(xcb_render_picture_t pic, ImageFilterType filter);
|
||||
SceneXrender *m_scene;
|
||||
xcb_render_pictformat_t format;
|
||||
double alpha_cached_opacity;
|
||||
QRegion transformed_shape;
|
||||
|
@ -135,7 +238,7 @@ private:
|
|||
inline
|
||||
xcb_render_picture_t SceneXrender::bufferPicture()
|
||||
{
|
||||
return buffer;
|
||||
return m_backend->buffer();
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
Loading…
Reference in a new issue