static void destroy_objects(struct gl_hwdec *hw) { struct priv *p = hw->priv; GL *gl = hw->gl; struct vdp_functions *vdp = &p->ctx->vdp; VdpStatus vdp_st; if (p->mapped) gl->VDPAUUnmapSurfacesNV(1, &p->vdpgl_surface); p->mapped = false; if (p->vdpgl_surface) gl->VDPAUUnregisterSurfaceNV(p->vdpgl_surface); p->vdpgl_surface = 0; glDeleteTextures(1, &p->gl_texture); p->gl_texture = 0; if (p->vdp_surface != VDP_INVALID_HANDLE) { vdp_st = vdp->output_surface_destroy(p->vdp_surface); CHECK_VDP_WARNING(p, "Error when calling vdp_output_surface_destroy"); } p->vdp_surface = VDP_INVALID_HANDLE; glCheckError(gl, hw->log, "Before uninitializing OpenGL interop"); gl->VDPAUFiniNV(); // If the GL/vdpau state is not initialized, above calls raises an error. while (1) { if (gl->GetError() == GL_NO_ERROR) break; } }
static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, GLuint *out_textures) { struct priv *p = hw->priv; GL *gl = hw->gl; assert(hw_image && hw_image->imgfmt == IMGFMT_VDPAU); int pe = mp_vdpau_handle_preemption(p->ctx, &p->preemption_counter); if (pe < 1) { mark_vdpau_objects_uninitialized(hw); if (pe < 0) return -1; if (reinit(hw, &p->image_params) < 0) return -1; } if (!p->vdpgl_surface) return -1; if (p->mapped) gl->VDPAUUnmapSurfacesNV(1, &p->vdpgl_surface); mp_vdpau_mixer_render(p->mixer, NULL, p->vdp_surface, NULL, hw_image, NULL); gl->VDPAUMapSurfacesNV(1, &p->vdpgl_surface); p->mapped = true; out_textures[0] = p->gl_texture; return 0; }
static void unmap_image(struct gl_hwdec *hw) { struct priv *p = hw->priv; GL *gl = hw->mpgl->gl; gl->VDPAUUnmapSurfacesNV(1, &p->vdpgl_surface); }
static void destroy_objects(struct gl_hwdec *hw) { struct priv *p = hw->priv; GL *gl = hw->gl; struct vdp_functions *vdp = &p->ctx->vdp; VdpStatus vdp_st; if (p->mapped) gl->VDPAUUnmapSurfacesNV(1, &p->vdpgl_surface); p->mapped = false; if (p->vdpgl_surface) gl->VDPAUUnregisterSurfaceNV(p->vdpgl_surface); p->vdpgl_surface = 0; glDeleteTextures(1, &p->gl_texture); p->gl_texture = 0; if (p->vdp_surface != VDP_INVALID_HANDLE) { vdp_st = vdp->output_surface_destroy(p->vdp_surface); CHECK_VDP_WARNING(p, "Error when calling vdp_output_surface_destroy"); } p->vdp_surface = VDP_INVALID_HANDLE; glCheckError(gl, hw->log, "Before uninitializing OpenGL interop"); if (p->vdpgl_initialized) gl->VDPAUFiniNV(); p->vdpgl_initialized = false; glCheckError(gl, hw->log, "After uninitializing OpenGL interop"); }
static void destroy_textures(struct gl_hwdec *hw) { struct priv *p = hw->priv; GL *gl = hw->gl; gl->DeleteTextures(4, p->gl_textures); for (int n = 0; n < 4; n++) p->gl_textures[n] = 0; }
void GLErrorRenderer::render(const G3MRenderContext *rc, const GLState& parentState) { GL* gl = rc->getGL(); const ILogger* logger = rc->getLogger(); int error = gl->getError(); while (error != GLError::noError()) { logger->logError("GL Error: %d", error); error = gl->getError(); } }
void BusyMeshRenderer::render(const G3MRenderContext* rc, GLState* glState) { GL* gl = rc->getGL(); createGLState(); gl->clearScreen(*_backgroundColor); Mesh* mesh = getMesh(rc); if (mesh != NULL) { mesh->render(rc, _glState); } }
static void releaseGlContext_wayland(MPGLContext *ctx) { GL *gl = ctx->gl; struct egl_context * egl_ctx = ctx->priv; gl->Finish(); eglMakeCurrent(egl_ctx->egl.dpy, NULL, NULL, EGL_NO_CONTEXT); eglDestroyContext(egl_ctx->egl.dpy, egl_ctx->egl.ctx); eglTerminate(egl_ctx->egl.dpy); eglReleaseThread(); wl_egl_window_destroy(egl_ctx->egl_window); egl_ctx->egl.ctx = NULL; }
static void releaseGlContext_wayland(MPGLContext *ctx) { GL *gl = ctx->gl; struct vo_wayland_state *wl = ctx->vo->wayland; gl->Finish(); eglReleaseThread(); wl_egl_window_destroy(wl->egl_context.egl_window); eglDestroySurface(wl->egl_context.egl.dpy, wl->egl_context.egl_surface); eglMakeCurrent(wl->egl_context.egl.dpy, NULL, NULL, EGL_NO_CONTEXT); eglDestroyContext(wl->egl_context.egl.dpy, wl->egl_context.egl.ctx); eglTerminate(wl->egl_context.egl.dpy); wl->egl_context.egl.ctx = NULL; }
static bool create_context_x11_old(struct MPGLContext *ctx) { struct glx_context *glx_ctx = ctx->priv; Display *display = ctx->vo->x11->display; struct vo *vo = ctx->vo; GL *gl = ctx->gl; if (glx_ctx->context) return true; GLXContext new_context = glXCreateContext(display, glx_ctx->vinfo, NULL, True); if (!new_context) { MP_FATAL(vo, "Could not create GLX context!\n"); return false; } if (!glXMakeCurrent(display, ctx->vo->x11->window, new_context)) { MP_FATAL(vo, "Could not set GLX context!\n"); glXDestroyContext(display, new_context); return false; } void *(*getProcAddress)(const GLubyte *); getProcAddress = mp_getdladdr("glXGetProcAddress"); if (!getProcAddress) getProcAddress = mp_getdladdr("glXGetProcAddressARB"); const char *glxstr = ""; const char *(*glXExtStr)(Display *, int) = mp_getdladdr("glXQueryExtensionsString"); if (glXExtStr) glxstr = glXExtStr(display, ctx->vo->x11->screen); mpgl_load_functions(gl, getProcAddress, glxstr, vo->log); if (!gl->GenPrograms && gl->GetString && gl->version < MPGL_VER(3, 0) && strstr(gl->GetString(GL_EXTENSIONS), "GL_ARB_vertex_program")) { MP_WARN(vo, "Broken glXGetProcAddress detected, trying workaround\n"); mpgl_load_functions(gl, NULL, glxstr, vo->log); } glx_ctx->context = new_context; if (!glXIsDirect(vo->x11->display, new_context)) ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW; return true; }
void Mark::render(const G3MRenderContext* rc, const Vector3D& cameraPosition) { const Planet* planet = rc->getPlanet(); const Vector3D* markPosition = getCartesianPosition(planet); const Vector3D markCameraVector = markPosition->sub(cameraPosition); // mark will be renderered only if is renderable by distance and placed on a visible globe area bool renderableByDistance; if (_minDistanceToCamera == 0) { renderableByDistance = true; } else { const double squaredDistanceToCamera = markCameraVector.squaredLength(); renderableByDistance = ( squaredDistanceToCamera <= (_minDistanceToCamera * _minDistanceToCamera) ); } _renderedMark = false; if (renderableByDistance) { const Vector3D normalAtMarkPosition = planet->geodeticSurfaceNormal(*markPosition); if (normalAtMarkPosition.angleBetween(markCameraVector)._radians > IMathUtils::instance()->halfPi()) { if (_textureId == NULL) { if (_textureImage != NULL) { _textureId = rc->getTexturesHandler()->getGLTextureId(_textureImage, GLFormat::rgba(), _imageID, false); rc->getFactory()->deleteImage(_textureImage); _textureImage = NULL; } } if (_textureId != NULL) { GL* gl = rc->getGL(); gl->drawBillBoard(_textureId, getVertices(planet), _textureWidth, _textureHeight); _renderedMark = true; } } } }
void TexturedMesh::render(const G3MRenderContext* rc, const GLState& parentState) const { GL* gl = rc->getGL(); GLState state(parentState); state.enableTextures(); state.enableTexture2D(); if (_transparent) { state.enableBlend(); gl->setBlendFuncSrcAlpha(); } _textureMapping->bind(rc); _mesh->render(rc, state); }
static void draw_frame(struct vo *vo, struct vo_frame *frame) { struct gl_priv *p = vo->priv; GL *gl = p->gl; if (gl->FenceSync && p->num_vsync_fences < p->opt_vsync_fences) { GLsync fence = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);; if (fence) p->vsync_fences[p->num_vsync_fences++] = fence; } gl_video_render_frame(p->renderer, frame, 0); if (p->use_glFinish) gl->Finish(); }
/** * \brief free the VisualInfo and GLXContext of an OpenGL context. * \ingroup glcontext */ static void releaseGlContext_x11(MPGLContext *ctx) { struct glx_context *glx_ctx = ctx->priv; XVisualInfo **vinfo = &glx_ctx->vinfo; GLXContext *context = &glx_ctx->context; Display *display = ctx->vo->x11->display; GL *gl = ctx->gl; if (*vinfo) XFree(*vinfo); *vinfo = NULL; if (*context) { if (gl->Finish) gl->Finish(); glXMakeCurrent(display, None, NULL); glXDestroyContext(display, *context); } *context = 0; }
static void flip_page(struct vo *vo) { struct gl_priv *p = vo->priv; GL *gl = p->gl; mpgl_lock(p->glctx); if (p->use_glFinish) gl->Finish(); p->glctx->swapGlBuffers(p->glctx); p->frames_rendered++; if (p->frames_rendered > 5) gl_video_set_debug(p->renderer, false); mpgl_unlock(p->glctx); }
static void destroy_texture(struct gl_hwdec *hw) { struct priv *p = hw->priv; GL *gl = hw->gl; if (p->glxpixmap) { p->glXReleaseTexImage(p->xdisplay, p->glxpixmap, GLX_FRONT_EXT); glXDestroyPixmap(p->xdisplay, p->glxpixmap); } p->glxpixmap = 0; if (p->pixmap) XFreePixmap(p->xdisplay, p->pixmap); p->pixmap = 0; gl->DeleteTextures(1, &p->gl_texture); p->gl_texture = 0; }
void BusyQuadRenderer::render(const G3MRenderContext* rc, const GLState& parentState) { GL* gl = rc->getGL(); GLState state(parentState); state.enableBlend(); if (_quadMesh == NULL){ if (!initMesh(rc)) { return; } } // init modelview matrix int currentViewport[4]; gl->getViewport(currentViewport); const int halfWidth = currentViewport[2] / 2; const int halfHeight = currentViewport[3] / 2; MutableMatrix44D M = MutableMatrix44D::createOrthographicProjectionMatrix(-halfWidth, halfWidth, -halfHeight, halfHeight, -halfWidth, halfWidth); gl->setProjection(M); gl->loadMatrixf(MutableMatrix44D::identity()); // clear screen gl->clearScreen(_backgroundColor->getRed(), _backgroundColor->getGreen(), _backgroundColor->getBlue(), _backgroundColor->getAlpha()); gl->setState(state); gl->setBlendFuncSrcAlpha(); gl->pushMatrix(); MutableMatrix44D R2 = MutableMatrix44D::createRotationMatrix(Angle::fromDegrees(_degrees), Vector3D(0, 0, 1)); gl->multMatrixf(R2); // draw mesh _quadMesh->render(rc, parentState); gl->popMatrix(); }
// check_window_only: assume params and dst/src rc are unchanged static void update_overlay(struct gl_hwdec *hw, bool check_window_only) { struct priv *p = hw->priv; GL *gl = hw->gl; MMAL_PORT_T *input = p->renderer->input[0]; struct mp_rect src = p->src; struct mp_rect dst = p->dst; if (!p->w || !p->h) return; int defs[4] = {0, 0, 0, 0}; int *z = gl->MPGetNativeDisplay ? gl->MPGetNativeDisplay("MPV_RPI_WINDOW") : NULL; if (!z) z = defs; // As documented in the libmpv openglcb headers. int display = z[0]; int layer = z[1]; int x = z[2]; int y = z[3]; if (check_window_only && memcmp(z, p->cur_window, sizeof(p->cur_window)) == 0) return; memcpy(p->cur_window, z, sizeof(p->cur_window)); int rotate[] = {MMAL_DISPLAY_ROT0, MMAL_DISPLAY_ROT90, MMAL_DISPLAY_ROT180, MMAL_DISPLAY_ROT270}; int src_w = src.x1 - src.x0, src_h = src.y1 - src.y0, dst_w = dst.x1 - dst.x0, dst_h = dst.y1 - dst.y0; int p_x, p_y; av_reduce(&p_x, &p_y, dst_w * src_h, src_w * dst_h, 16000); MMAL_DISPLAYREGION_T dr = { .hdr = { .id = MMAL_PARAMETER_DISPLAYREGION, .size = sizeof(MMAL_DISPLAYREGION_T), }, .src_rect = { .x = src.x0, .y = src.y0, .width = src_w, .height = src_h }, .dest_rect = { .x = dst.x0 + x, .y = dst.y0 + y,
static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, GLuint *out_textures) { struct priv *p = hw->priv; GL *gl = hw->mpgl->gl; assert(hw_image && hw_image->imgfmt == IMGFMT_VDPAU); if (handle_preemption(hw) < 0) return -1; if (!p->vdpgl_surface) return -1; mp_vdpau_mixer_render(p->mixer, NULL, p->vdp_surface, NULL, hw_image, NULL); gl->VDPAUMapSurfacesNV(1, &p->vdpgl_surface); out_textures[0] = p->gl_texture; return 0; }
static int create(struct gl_hwdec *hw) { GL *gl = hw->gl; if (hw->hwctx || !gl->MPGetD3DInterface) return -1; struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; p->ctx.d3d9_device = gl->MPGetD3DInterface("IDirect3DDevice9"); if (!p->ctx.d3d9_device) return -1; p->ctx.hwctx.type = HWDEC_DXVA2_COPY; p->ctx.hwctx.d3d_ctx = &p->ctx; MP_VERBOSE(hw, "Using libmpv supplied device %p.\n", p->ctx.d3d9_device); hw->hwctx = &p->ctx.hwctx; hw->converted_imgfmt = 0; return 0; }
static int reinit(struct gl_hwdec *hw, struct mp_image_params *params) { struct priv *p = hw->priv; GL *gl = hw->gl; struct vdp_functions *vdp = &p->ctx->vdp; VdpStatus vdp_st; destroy_objects(hw); assert(params->imgfmt == hw->driver->imgfmt); p->image_params = *params; if (mp_vdpau_handle_preemption(p->ctx, &p->preemption_counter) < 0) return -1; gl->VDPAUInitNV(BRAINDEATH(p->ctx->vdp_device), p->ctx->get_proc_address); p->vdpgl_initialized = true; vdp_st = vdp->output_surface_create(p->ctx->vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, params->w, params->h, &p->vdp_surface); CHECK_VDP_ERROR(p, "Error when calling vdp_output_surface_create"); gl->GenTextures(1, &p->gl_texture); gl->BindTexture(GL_TEXTURE_2D, p->gl_texture); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->BindTexture(GL_TEXTURE_2D, 0); p->vdpgl_surface = gl->VDPAURegisterOutputSurfaceNV(BRAINDEATH(p->vdp_surface), GL_TEXTURE_2D, 1, &p->gl_texture); if (!p->vdpgl_surface) return -1; gl->VDPAUSurfaceAccessNV(p->vdpgl_surface, GL_READ_ONLY); glCheckError(gl, hw->log, "After initializing vdpau OpenGL interop"); return 0; }
static bool create_context_w32_old(struct MPGLContext *ctx) { GL *gl = ctx->gl; struct w32_context *w32_ctx = ctx->priv; HGLRC *context = &w32_ctx->context; if (*context) { gl->Finish(); // supposedly to prevent flickering return true; } HWND win = ctx->vo->w32->window; HDC windc = GetDC(win); bool res = false; HGLRC new_context = wglCreateContext(windc); if (!new_context) { MP_FATAL(ctx->vo, "Could not create GL context!\n"); goto out; } if (!wglMakeCurrent(windc, new_context)) { MP_FATAL(ctx->vo, "Could not set GL context!\n"); wglDeleteContext(new_context); goto out; } *context = new_context; mpgl_load_functions(ctx->gl, w32gpa, NULL, ctx->vo->log); res = true; out: ReleaseDC(win, windc); return res; }
int main(int argc, char *argv[]) { GL gl; ToyouraPNG toyoura; ObjectColor red(1.0, 0.0, 0.0); ObjectColor blue(0.0, 1.0, 0.0); ObjectColor white(1.f, 1.f, 1.f); ObjectColor gray(0.5, 0.5, 0.5); Math3D::Quaternion quat; Math3D::Degree angle(120); Math3D::Vector3 pos(0, 0, 1); quat.fromAngleAxis(angle, pos); GLTexture texture(toyoura); pGLSphere sphere(new GLSphere); pGLFloor floor(new GLFloor); sphere -> setColor(red); sphere -> setSize(10); floor -> setTexture(texture); floor -> setAttitude(quat); floor -> setSize(100.f, 100.f); /* pCube cube(new Cube); pSphere sphere(new Sphere); pFloor floor(new Floor); pAxis axis(new Axis); pCylinder cylinder(new Cylinder); cube-> setSize(5, 5, 5); cube-> setPosition(30, 0, 0); sphere -> setPosition(0, 10, 0); sphere -> setAttitude(quat); cylinder -> setColor(blue); cylinder -> setAttitude(quat); cylinder -> setAttitude(quat); cylinder -> setSize(5, 10); glfw.pushObject(floor); glfw.pushObject(axis); glfw.pushObject(cylinder); glfw.pushObject(cube); */ gl.pushObject(sphere); gl.pushObject(floor); gl.setCamera(); gl.setLight(); gl.run(); return 0; }
static int reinit(struct gl_hwdec *hw, struct mp_image_params *params) { struct priv *p = hw->priv; GL *gl = hw->gl; destroy_texture(hw); params->imgfmt = hw->driver->imgfmt; gl->GenTextures(1, &p->gl_texture); gl->BindTexture(GL_TEXTURE_2D, p->gl_texture); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->BindTexture(GL_TEXTURE_2D, 0); p->pixmap = XCreatePixmap(p->xdisplay, RootWindow(p->xdisplay, DefaultScreen(p->xdisplay)), params->w, params->h, 24); if (!p->pixmap) { MP_FATAL(hw, "could not create pixmap\n"); return -1; } int attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, GLX_MIPMAP_TEXTURE_EXT, False, None, }; p->glxpixmap = glXCreatePixmap(p->xdisplay, p->fbc, p->pixmap, attribs); gl->BindTexture(GL_TEXTURE_2D, p->gl_texture); p->glXBindTexImage(p->xdisplay, p->glxpixmap, GLX_FRONT_EXT, NULL); gl->BindTexture(GL_TEXTURE_2D, 0); return 0; }
static int reinit(struct gl_hwdec *hw, int w, int h) { struct priv *p = hw->priv; GL *gl = hw->mpgl->gl; VAStatus status; destroy_texture(hw); gl->GenTextures(1, &p->gl_texture); gl->BindTexture(GL_TEXTURE_2D, p->gl_texture); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); gl->BindTexture(GL_TEXTURE_2D, 0); status = vaCreateSurfaceGLX(p->display, GL_TEXTURE_2D, p->gl_texture, &p->vaglx_surface); return check_va_status(status, "vaCreateSurfaceGLX()") ? 0 : -1; }
static int reinit(struct gl_hwdec *hw, const struct mp_image_params *params) { struct priv *p = hw->priv; GL *gl = hw->mpgl->gl; VAStatus status; destroy_texture(hw); gl->GenTextures(1, &p->gl_texture); gl->BindTexture(GL_TEXTURE_2D, p->gl_texture); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params->w, params->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); gl->BindTexture(GL_TEXTURE_2D, 0); va_lock(p->ctx); status = vaCreateSurfaceGLX(p->display, GL_TEXTURE_2D, p->gl_texture, &p->vaglx_surface); va_unlock(p->ctx); return CHECK_VA_STATUS(p, "vaCreateSurfaceGLX()") ? 0 : -1; }
static int reinit(struct gl_hwdec *hw, struct mp_image_params *params) { struct priv *p = hw->priv; GL *gl = hw->gl; // Recreate them to get rid of all previous image data (possibly). destroy_textures(hw); assert(params->imgfmt == hw->driver->imgfmt); gl->GenTextures(4, p->gl_textures); for (int n = 0; n < 4; n++) { gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } gl->BindTexture(GL_TEXTURE_2D, 0); return 0; }
static void flip_page(struct vo *vo) { struct gl_priv *p = vo->priv; GL *gl = p->gl; mpgl_swap_buffers(p->glctx); p->frames_rendered++; if (p->frames_rendered > 5 && !p->use_gl_debug) gl_video_set_debug(p->renderer, false); if (p->use_glFinish) gl->Finish(); if (p->waitvsync || p->opt_pattern[0]) { if (gl->GetVideoSync) { unsigned int n1 = 0, n2 = 0; gl->GetVideoSync(&n1); if (p->waitvsync) gl->WaitVideoSync(2, (n1 + 1) % 2, &n2); int step = n1 - p->prev_sgi_sync_count; p->prev_sgi_sync_count = n1; MP_DBG(vo, "Flip counts: %u->%u, step=%d\n", n1, n2, step); if (p->opt_pattern[0]) check_pattern(vo, step); } else { MP_WARN(vo, "GLX_SGI_video_sync not available, disabling.\n"); p->waitvsync = 0; p->opt_pattern[0] = 0; } } while (p->opt_vsync_fences > 0 && p->num_vsync_fences >= p->opt_vsync_fences) { gl->ClientWaitSync(p->vsync_fences[0], GL_SYNC_FLUSH_COMMANDS_BIT, 1e9); gl->DeleteSync(p->vsync_fences[0]); MP_TARRAY_REMOVE_AT(p->vsync_fences, p->num_vsync_fences, 0); } }
void IndexedMesh::rawRender(const G3MRenderContext* rc, const GLState& parentState) const { GL* gl = rc->getGL(); gl->drawElements(_primitive, _indices); }
static int init(struct ra_hwdec *hw) { struct priv_owner *p = hw->priv; if (!ra_is_gl(hw->ra)) return -1; GL *gl = ra_gl_get(hw->ra); if (!(gl->mpgl_caps & MPGL_CAP_DXINTEROP)) return -1; // AMD drivers won't open multiple dxinterop HANDLES on the same D3D device, // so we request the one already in use by context_dxinterop p->device_h = mpgl_get_native_display(gl, "dxinterop_device_HANDLE"); if (!p->device_h) return -1; // But we also still need the actual D3D device p->device = mpgl_get_native_display(gl, "IDirect3DDevice9Ex"); if (!p->device) return -1; IDirect3DDevice9Ex_AddRef(p->device); p->hwctx = (struct mp_hwdec_ctx){ .driver_name = hw->driver->name, .av_device_ref = d3d9_wrap_device_ref((IDirect3DDevice9 *)p->device), }; hwdec_devices_add(hw->devs, &p->hwctx); return 0; } static void mapper_uninit(struct ra_hwdec_mapper *mapper) { struct priv *p = mapper->priv; GL *gl = ra_gl_get(mapper->ra); if (p->rtarget_h && p->device_h) { if (!gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h)) { MP_ERR(mapper, "Failed unlocking texture for access by OpenGL: %s\n", mp_LastError_to_str()); } } if (p->rtarget_h) { if (!gl->DXUnregisterObjectNV(p->device_h, p->rtarget_h)) { MP_ERR(mapper, "Failed to unregister Direct3D surface with OpenGL: %s\n", mp_LastError_to_str()); } else { p->rtarget_h = 0; } } gl->DeleteTextures(1, &p->texture); p->texture = 0; if (p->rtarget) { IDirect3DSurface9_Release(p->rtarget); p->rtarget = NULL; } ra_tex_free(mapper->ra, &mapper->tex[0]); } static int mapper_init(struct ra_hwdec_mapper *mapper) { struct priv_owner *p_owner = mapper->owner->priv; struct priv *p = mapper->priv; GL *gl = ra_gl_get(mapper->ra); HRESULT hr; p->device = p_owner->device; p->device_h = p_owner->device_h; HANDLE share_handle = NULL; hr = IDirect3DDevice9Ex_CreateRenderTarget( p->device, mapper->src_params.w, mapper->src_params.h, SHARED_SURFACE_D3DFMT, D3DMULTISAMPLE_NONE, 0, FALSE, &p->rtarget, &share_handle); if (FAILED(hr)) { MP_ERR(mapper, "Failed creating offscreen Direct3D surface: %s\n", mp_HRESULT_to_str(hr)); return -1; } if (share_handle && !gl->DXSetResourceShareHandleNV(p->rtarget, share_handle)) { MP_ERR(mapper, "Failed setting Direct3D/OpenGL share handle for surface: %s\n", mp_LastError_to_str()); return -1; } gl->GenTextures(1, &p->texture); gl->BindTexture(GL_TEXTURE_2D, p->texture); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->BindTexture(GL_TEXTURE_2D, 0); p->rtarget_h = gl->DXRegisterObjectNV(p->device_h, p->rtarget, p->texture, GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV); if (!p->rtarget_h) { MP_ERR(mapper, "Failed to register Direct3D surface with OpenGL: %s\n", mp_LastError_to_str()); return -1; } if (!gl->DXLockObjectsNV(p->device_h, 1, &p->rtarget_h)) { MP_ERR(mapper, "Failed locking texture for access by OpenGL %s\n", mp_LastError_to_str()); return -1; } struct ra_tex_params params = { .dimensions = 2, .w = mapper->src_params.w, .h = mapper->src_params.h, .d = 1, .format = ra_find_unorm_format(mapper->ra, 1, 4), .render_src = true, .src_linear = true, }; if (!params.format) return -1; mapper->tex[0] = ra_create_wrapped_tex(mapper->ra, ¶ms, p->texture); if (!mapper->tex[0]) return -1; mapper->dst_params = mapper->src_params; mapper->dst_params.imgfmt = IMGFMT_RGB0; mapper->dst_params.hw_subfmt = 0; return 0; } static int mapper_map(struct ra_hwdec_mapper *mapper) { struct priv *p = mapper->priv; GL *gl = ra_gl_get(mapper->ra); HRESULT hr; if (!gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h)) { MP_ERR(mapper, "Failed unlocking texture for access by OpenGL: %s\n", mp_LastError_to_str()); return -1; } IDirect3DSurface9* hw_surface = (IDirect3DSurface9 *)mapper->src->planes[3]; RECT rc = {0, 0, mapper->src->w, mapper->src->h}; hr = IDirect3DDevice9Ex_StretchRect(p->device, hw_surface, &rc, p->rtarget, &rc, D3DTEXF_NONE); if (FAILED(hr)) { MP_ERR(mapper, "Direct3D RGB conversion failed: %s", mp_HRESULT_to_str(hr)); return -1; } if (!gl->DXLockObjectsNV(p->device_h, 1, &p->rtarget_h)) { MP_ERR(mapper, "Failed locking texture for access by OpenGL: %s\n", mp_LastError_to_str()); return -1; } return 0; } const struct ra_hwdec_driver ra_hwdec_dxva2gldx = { .name = "dxva2-dxinterop", .priv_size = sizeof(struct priv_owner), .imgfmts = {IMGFMT_DXVA2, 0}, .init = init, .uninit = uninit, .mapper = &(const struct ra_hwdec_mapper_driver){ .priv_size = sizeof(struct priv), .init = mapper_init, .uninit = mapper_uninit, .map = mapper_map, }, };