cairo_surface_t* RedirectedXCompositeWindow::cairoSurfaceForWidget(GtkWidget* widget)
{
    if (!m_needsNewPixmapAfterResize && m_surface)
        return m_surface.get();

    m_needsNewPixmapAfterResize = false;

    // It's important that the new pixmap be created with the same Display pointer as the target
    // widget or else drawing speed can be 100x slower.
    Display* newPixmapDisplay = GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(widget));
    Pixmap newPixmap = XCompositeNameWindowPixmap(newPixmapDisplay, m_window);
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return 0;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(newPixmapDisplay, m_window, &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        XFreePixmap(newPixmapDisplay, newPixmap);
        return 0;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(newPixmapDisplay, newPixmap,
                                                                            windowAttributes.visual,
                                                                            m_size.width(), m_size.height()));

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
        cairo_set_source_rgb(cr.get(), 1, 1, 1);
        cairo_paint(cr.get());
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = newPixmap;
    m_surface = newSurface;

    return m_surface.get();
}
Exemplo n.º 2
0
cairo_surface_t* RedirectedXCompositeWindow::surface()
{
    // This should never be called with an empty size (not in Accelerated Compositing mode).
    ASSERT(!m_size.isEmpty());

    if (!m_needsNewPixmapAfterResize && m_surface)
        return m_surface.get();

    m_needsNewPixmapAfterResize = false;

    Pixmap newPixmap = XCompositeNameWindowPixmap(m_display, m_window);
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return nullptr;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(m_display, m_window, &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        XFreePixmap(m_display, newPixmap);
        return nullptr;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap, windowAttributes.visual, m_size.width(), m_size.height()));

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
        cairo_set_source_rgb(cr.get(), 1, 1, 1);
        cairo_paint(cr.get());
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = newPixmap;
    m_surface = newSurface;
    return m_surface.get();
}
Exemplo n.º 3
0
void RedirectedXCompositeWindow::createNewPixampAndPixampSurface()
{
    // This should never be called with an empty size (not in Accelerated Compositing mode).
    ASSERT(!m_size.isEmpty());
    XUniquePixmap newPixmap(XCompositeNameWindowPixmap(m_display, m_window.get()));
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(m_display, m_window.get(), &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        return;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap.get(), windowAttributes.visual, m_size.width(), m_size.height()));
    cairoSurfaceSetDeviceScale(newSurface.get(), m_webPage.deviceScaleFactor(), m_webPage.deviceScaleFactor());

    RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
    if (!m_webPage.drawsBackground())
        cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR);
    else
        setSourceRGBAFromColor(cr.get(), m_webPage.backgroundColor());
    cairo_paint(cr.get());

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        cairo_set_operator(cr.get(), CAIRO_OPERATOR_OVER);
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = WTFMove(newPixmap);
    m_surface = WTFMove(newSurface);
}
Exemplo n.º 4
0
void RedirectedXCompositeWindow::resize(const IntSize& size)
{
    if (size == m_size)
        return;

    // Resize the window to at last 1x1 since X doesn't allow to create empty windows.
    XResizeWindow(m_display, m_window, std::max(1, size.width()), std::max(1, size.height()));
    XFlush(m_display);

    m_size = size;
    m_needsNewPixmapAfterResize = true;
    if (m_size.isEmpty())
        cleanupPixmapAndPixmapSurface();
}
Exemplo n.º 5
0
RedirectedXCompositeWindow::~RedirectedXCompositeWindow()
{
    ASSERT(m_display);
    ASSERT(m_damage);
    ASSERT(m_window);
    ASSERT(m_parentWindow);

    xDamageNotifier().remove(m_window);

    XDamageDestroy(m_display, m_damage);
    XDestroyWindow(m_display, m_window);
    XDestroyWindow(m_display, m_parentWindow);
    cleanupPixmapAndPixmapSurface();
}
RedirectedXCompositeWindow::~RedirectedXCompositeWindow()
{
    ASSERT(m_damage);
    ASSERT(m_window);
    ASSERT(m_parentWindow);

    getWindowHashMap().remove(m_window);
    if (getWindowHashMap().isEmpty())
        gdk_window_remove_filter(0, reinterpret_cast<GdkFilterFunc>(filterXDamageEvent), 0);

    Display* display = GLContext::sharedX11Display();
    XDamageDestroy(display, m_damage);
    XDestroyWindow(display, m_window);
    XDestroyWindow(display, m_parentWindow);
    cleanupPixmapAndPixmapSurface();
}
Exemplo n.º 7
0
void RedirectedXCompositeWindow::resize(const IntSize& size)
{
    IntSize scaledSize(size);
    scaledSize.scale(m_webPage.deviceScaleFactor());
    if (scaledSize == m_size)
        return;

    // Resize the window to at last 1x1 since X doesn't allow to create empty windows.
    XResizeWindow(m_display, m_window.get(), std::max(1, scaledSize.width()), std::max(1, scaledSize.height()));
    XFlush(m_display);

    m_size = scaledSize;
    if (m_size.isEmpty())
        cleanupPixmapAndPixmapSurface();
    else
        createNewPixampAndPixampSurface();
}