bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy) { if (m_backBuffer.isNull()) return false; Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class); // Make sure all GL rendering is complete before starting the scroll operation: QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context(); if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) ctx->makeCurrent(); eglWaitClient(); if (!m_pixmapGC) m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); foreach (const QRect& rect, area.rects()) { XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC, rect.x(), rect.y(), rect.width(), rect.height(), rect.x()+dx, rect.y()+dy); } // Make sure the scroll operation is complete before allowing GL rendering to resume eglWaitNative(EGL_CORE_NATIVE_ENGINE); return true; }
void resize(int w, int h) { if (w == width && h == height) { return; } eglWaitClient(); // We need to ensure that pending events are processed here, and XSync // with discard = True guarantees that, but it appears the limited // event processing we do so far is sufficient //XSync(display, True); Drawable::resize(w, h); XResizeWindow(display, window, w, h); // Tell the window manager to respect the requested size XSizeHints size_hints; size_hints.max_width = size_hints.min_width = w; size_hints.max_height = size_hints.min_height = h; size_hints.flags = PMinSize | PMaxSize; XSetWMNormalHints(display, window, &size_hints); waitForEvent(ConfigureNotify); eglWaitNative(EGL_CORE_NATIVE_ENGINE); }
~EglDrawable() { eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(eglDisplay, surface); eglWaitClient(); eglWaitNative(EGL_CORE_NATIVE_ENGINE); }
void show(void) { if (visible) { return; } eglWaitClient(); eglWaitNative(EGL_CORE_NATIVE_ENGINE); Drawable::show(); }
/* EGLBoolean eglWaitNative ( EGLint engine ) */ static jboolean android_eglWaitNative (JNIEnv *_env, jobject _this, jint engine) { EGLBoolean _returnValue = (EGLBoolean) 0; _returnValue = eglWaitNative( (EGLint)engine ); return (jboolean)_returnValue; }
EglDrawable(const Visual *vis, int w, int h, bool pbuffer) : Drawable(vis, w, h, pbuffer), api(EGL_OPENGL_ES_API), windowId(0) { eglWaitNative(EGL_CORE_NATIVE_ENGINE); const EglVisual * eglVisual = static_cast<const EglVisual *>(visual); update(); ANativeWindow_setBuffersGeometry(window.get(), 0, 0, eglVisual->format); surface = eglCreateWindowSurface(eglDisplay, eglVisual->config, window.get(), NULL); }
QRegion EglWaylandBackend::prepareRenderingFrame() { if (!lastDamage().isEmpty()) present(); QRegion repaint; if (supportsBufferAge()) repaint = accumulatedDamageHistory(m_bufferAge); eglWaitNative(EGL_CORE_NATIVE_ENGINE); startRenderTimer(); return repaint; }
/* private native int _eglWaitNative ( int engine ) ; */ KNIEXPORT KNI_RETURNTYPE_INT Java_javax_microedition_khronos_egl_EGL10Impl__1eglWaitNative() { jint engine = KNI_GetParameterAsInt(1); jint returnValue = (jint)eglWaitNative(engine); #ifdef DEBUG printf("eglWaitNative(%d) = %d\n", engine, returnValue); #endif KNI_ReturnInt(returnValue); }
EglDrawable(const Visual *vis, int w, int h, bool pbuffer) : Drawable(vis, w, h, pbuffer), api(EGL_OPENGL_ES_API) { XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo; const char *name = "eglretrace"; window = createWindow(visinfo, name, width, height); eglWaitNative(EGL_CORE_NATIVE_ENGINE); EGLConfig config = static_cast<const EglVisual *>(visual)->config; surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL); }
void resize(int w, int h) { if (w == width && h == height) { return; } eglWaitClient(); // We need to ensure that pending events are processed here, and XSync // with discard = True guarantees that, but it appears the limited // event processing we do so far is sufficient //XSync(display, True); Drawable::resize(w, h); XResizeWindow(display, window, w, h); // Tell the window manager to respect the requested size XSizeHints size_hints; size_hints.max_width = size_hints.min_width = w; size_hints.max_height = size_hints.min_height = h; size_hints.flags = PMinSize | PMaxSize; XSetWMNormalHints(display, window, &size_hints); waitForEvent(ConfigureNotify); eglWaitNative(EGL_CORE_NATIVE_ENGINE); /* * Some implementations won't update the backbuffer unless we recreate * the EGL surface. */ int eglWidth; int eglHeight; eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth); eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight); if (eglWidth != width || eglHeight != height) { recreate(); eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth); eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight); } assert(eglWidth == width); assert(eglHeight == height); }
void show(void) { if (visible) { return; } eglWaitClient(); XMapWindow(display, window); waitForEvent(MapNotify); eglWaitNative(EGL_CORE_NATIVE_ENGINE); Drawable::show(); }
EglDrawable(const Visual *vis, int w, int h, bool pbuffer) : Drawable(vis, w, h, pbuffer), api(EGL_OPENGL_ES_API) { XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo; Window root = RootWindow(display, screen); /* window attributes */ XSetWindowAttributes attr; attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask; unsigned long mask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; int x = 0, y = 0; window = XCreateWindow( display, root, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(display, window, &sizehints); const char *name = "glretrace"; XSetStandardProperties( display, window, name, name, None, (char **)NULL, 0, &sizehints); eglWaitNative(EGL_CORE_NATIVE_ENGINE); EGLConfig config = static_cast<const EglVisual *>(visual)->config; surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL); }
void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset) { // We don't need to know the widget which initiated the flush. Instead we just use the offset // to translate the widgetRegion: Q_UNUSED(widget); if (m_backBuffer.isNull()) { qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything"); return; } Q_ASSERT(window()->size() != m_backBuffer.size()); // Wait for all GL rendering to the back buffer pixmap to complete before trying to // copy it to the window. We do this by making sure the pixmap's context is current // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to // block, just that "All rendering calls...are guaranteed to be executed before native // rendering calls". This makes it potentially less expensive than glFinish. QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context(); if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) ctx->makeCurrent(); eglWaitClient(); if (m_windowGC == 0) { XGCValues attribs; attribs.graphics_exposures = False; m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs); } int rectCount; XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount); if (rectCount <= 0) return; XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded); QRect dirtyRect = widgetRegion.boundingRect().translated(-offset); XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC, dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), dirtyRect.x(), dirtyRect.y()); // Make sure the blit of the update from the back buffer to the window completes // before allowing rendering to start again to the back buffer. Otherwise the GPU // might start rendering to the back buffer again while the blit takes place. eglWaitNative(EGL_CORE_NATIVE_ENGINE); }
QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const { if (!widget || m_backBuffer.isNull()) return QPixmap(); QRect srcRect; // make sure the rect is inside the widget & clip to widget's rect if (!rect.isEmpty()) srcRect = rect & widget->rect(); else srcRect = widget->rect(); if (srcRect.isEmpty()) return QPixmap(); // If it's a child widget we have to translate the coordinates if (widget != window()) srcRect.translate(widget->mapTo(window(), QPoint(0, 0))); QPixmap::x11SetDefaultScreen(widget->x11Info().screen()); QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType); pmd->resize(srcRect.width(), srcRect.height()); QPixmap px(pmd); GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); // Make sure all GL rendering is complete before copying the window QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context(); if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) ctx->makeCurrent(); eglWaitClient(); // Copy srcRect from the backing store to the new pixmap XSetGraphicsExposures(X11->display, tmpGc, False); XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0); XFreeGC(X11->display, tmpGc); // Wait until the copy has finised before allowing more rendering into the back buffer eglWaitNative(EGL_CORE_NATIVE_ENGINE); return px; }
void EGLTextureFromPixmap::destroy() { eglWaitNative(EGL_CORE_NATIVE_ENGINE); if (m_surface != EGL_NO_SURFACE) eglReleaseTexImage(EGLHelper::eglDisplay(), m_surface, EGL_BACK_BUFFER); if (m_eglImage) { EGLHelper::destroyEGLImage(m_eglImage); m_eglImage = 0; } if (m_surface != EGL_NO_SURFACE) { eglDestroySurface(EGLHelper::eglDisplay(), m_surface); m_surface = EGL_NO_SURFACE; } eglWaitGL(); }
static void clutter_backend_egl_redraw (ClutterBackend *backend, ClutterStage *stage) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend); ClutterStageEGL *stage_egl; ClutterStageWindow *impl; impl = _clutter_stage_get_window (stage); if (!impl) return; g_assert (CLUTTER_IS_STAGE_EGL (impl)); stage_egl = CLUTTER_STAGE_EGL (impl); eglWaitNative (EGL_CORE_NATIVE_ENGINE); clutter_actor_paint (CLUTTER_ACTOR (stage)); cogl_flush (); eglWaitGL(); eglSwapBuffers (backend_egl->edpy, stage_egl->egl_surface); }
void resize(int w, int h) { if (w == width && h == height) { return; } eglWaitClient(); // We need to ensure that pending events are processed here, and XSync // with discard = True guarantees that, but it appears the limited // event processing we do so far is sufficient //XSync(display, True); Drawable::resize(w, h); resizeWindow(window, w, h); eglWaitNative(EGL_CORE_NATIVE_ENGINE); /* * Some implementations won't update the backbuffer unless we recreate * the EGL surface. */ int eglWidth; int eglHeight; eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth); eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight); if (eglWidth != width || eglHeight != height) { recreate(); eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth); eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight); } assert(eglWidth == width); assert(eglHeight == height); }
QRegion EglOnXBackend::prepareRenderingFrame() { QRegion repaint; if (gs_tripleBufferNeedsDetection) { // the composite timer floors the repaint frequency. This can pollute our triple buffering // detection because the glXSwapBuffers call for the new frame has to wait until the pending // one scanned out. // So we compensate for that by waiting an extra milisecond to give the driver the chance to // fllush the buffer queue usleep(1000); } present(); if (supportsBufferAge()) repaint = accumulatedDamageHistory(m_bufferAge); startRenderTimer(); eglWaitNative(EGL_CORE_NATIVE_ENGINE); return repaint; }
static void app_redraw(struct app_data *data) { /* pixmap has changed */ if (data->reshape || data->paint.active) { /* * The extension only states that * * If an application specifies an EGLImage sibling as the destination * for rendering and/or pixel download operations (e.g., as an * OpenGL-ES framebuffer object, glTexSubImage2D, etc.), the modified * image results will be observed by all EGLImage siblings in all * client API contexts. * * Though not required by the drivers I tested, I think the rules of * "Propagating Changes to Objects" should apply here. That is, the * changes made by the native engine must be completed and the resource * must be re-attached. */ eglWaitNative(EGL_CORE_NATIVE_ENGINE); data->glEGLImageTargetTexture2DOES(data->target, (GLeglImageOES) data->img); } XCopyArea(data->xdpy, data->pix, data->canvas, data->fg, 0, 0, data->width, data->height, 0, 0); glPushMatrix(); glRotatef(data->animate.view_rotx, 1, 0, 0); glRotatef(data->animate.view_roty, 0, 1, 0); glRotatef(data->animate.view_rotz, 0, 0, 1); gl_redraw(); glPopMatrix(); eglSwapBuffers(data->dpy, data->surf); }
// Wait for native rendering operations to complete before starting // to use OpenGL/OpenVG operations. void QEglContext::waitNative() { #ifdef EGL_CORE_NATIVE_ENGINE eglWaitNative(EGL_CORE_NATIVE_ENGINE); #endif }
void GLContextEGL::waitNative() { eglWaitNative(EGL_CORE_NATIVE_ENGINE); }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengles_EGL_eglWaitNative(JNIEnv *env, jclass clazz, jint engine) { return eglWaitNative(engine); }
static jboolean jni_eglWaitNative(JNIEnv *_env, jobject _this, jint engine, jobject bindTarget) { return eglWaitNative(engine); }
~EglDrawable() { eglDestroySurface(eglDisplay, surface); eglWaitClient(); XDestroyWindow(display, window); eglWaitNative(EGL_CORE_NATIVE_ENGINE); }