Exemple #1
0
bool EGLInteropResource::map(IDirect3DSurface9* surface, GLuint tex, int w, int h, int H)
{
    D3DSURFACE_DESC dxvaDesc;
    surface->GetDesc(&dxvaDesc);
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    const RECT src = { 0, 0, w, h};
    HRESULT ret = device9->StretchRect(surface, &src, surface9, NULL, D3DTEXF_NONE);
    if (SUCCEEDED(ret)) {
        if (query9) {
            // Flush the draw command now. Ideally, this should be done immediately before the draw call that uses the texture. Flush it once here though.
            query9->Issue(D3DISSUE_END);
            // ensure data is copied to egl surface. Solution and comment is from chromium
            // The DXVA decoder has its own device which it uses for decoding. ANGLE has its own device which we don't have access to.
            // The above code attempts to copy the decoded picture into a surface which is owned by ANGLE.
            // As there are multiple devices involved in this, the StretchRect call above is not synchronous.
            // We attempt to flush the batched operations to ensure that the picture is copied to the surface owned by ANGLE.
            // We need to do this in a loop and call flush multiple times.
            // We have seen the GetData call for flushing the command buffer fail to return success occassionally on multi core machines, leading to an infinite loop.
            // Workaround is to have an upper limit of 10 on the number of iterations to wait for the Flush to finish.
            int k = 0;
            // skip at decoder.close()
            while (/*!skip_dx.load() && */(query9->GetData(NULL, 0, D3DGETDATA_FLUSH) == FALSE) && ++k < 10) {
                Sleep(1);
            }
        }
        eglBindTexImage(egl->dpy, egl->surface, EGL_BACK_BUFFER);
    } else {
        qWarning() << "map to egl error: " << ret << " - " << qt_error_string(ret);
    }
    DYGL(glBindTexture(GL_TEXTURE_2D, 0));
    return true;
}
Exemple #2
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    Q_EMIT beforeRendering();
    DYGL(glViewport(d.rect.x(), d.rect.y(), d.rect.width(), d.rect.height())); // viewport was used in gpu filters is wrong, qt quick fbo item's is right(so must ensure setProjectionMatrixToRect was called correctly)
    const qint64 mt = d.material->type();
    if (d.material_type != mt) {
        qDebug() << "material changed: " << VideoMaterial::typeName(d.material_type) << " => " << VideoMaterial::typeName(mt);
        d.material_type = mt;
    }
    VideoShader *shader = d.user_shader;
    if (!shader)
        shader = d.manager->prepareMaterial(d.material, mt); //TODO: print shader type name if changed. prepareMaterial(,sample_code, pp_code)
    shader->update(d.material);
    d.material->setDirty(false); //
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    d.gr.setShaderProgram(shader->program());
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    d.gr.render(&d.geometry);
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();

    Q_EMIT afterRendering();
}
bool EGLInteropResource::map(IDirect3DSurface9* surface, GLuint tex, int w, int h, int)
{
    if (!ensureSurface(w, h)) {
        releaseEGL();
        releaseDX();
        return false;
    }
    const RECT src = { 0, 0, (~0-1)&w, (~0-1)&h};
    DX_ENSURE(d3ddev->StretchRect(surface, &src, dx_surface, NULL, D3DTEXF_NONE), false);
    if (dx_query) {
        // Flush the draw command now. Ideally, this should be done immediately before the draw call that uses the texture. Flush it once here though.
        dx_query->Issue(D3DISSUE_END); //StretchRect does not supports odd values
        // ensure data is copied to egl surface. Solution and comment is from chromium
        // The DXVA decoder has its own device which it uses for decoding. ANGLE has its own device which we don't have access to.
        // The above code attempts to copy the decoded picture into a surface which is owned by ANGLE.
        // As there are multiple devices involved in this, the StretchRect call above is not synchronous.
        // We attempt to flush the batched operations to ensure that the picture is copied to the surface owned by ANGLE.
        // We need to do this in a loop and call flush multiple times.
        // We have seen the GetData call for flushing the command buffer fail to return success occassionally on multi core machines, leading to an infinite loop.
        // Workaround is to have an upper limit of 10 on the number of iterations to wait for the Flush to finish.
        int k = 0;
        while ((dx_query->GetData(NULL, 0, D3DGETDATA_FLUSH) == FALSE) && ++k < 10) {
            Sleep(1);
        }
    }
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    eglBindTexImage(egl->dpy, egl->surface, EGL_BACK_BUFFER);
    DYGL(glBindTexture(GL_TEXTURE_2D, 0));
    return true;
}
Exemple #4
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    const qint64 mt = d.material->type();
    if (d.material_type != mt) {
        qDebug() << "material changed: " << VideoMaterial::typeName(d.material_type) << " => " << VideoMaterial::typeName(mt);
        d.material_type = mt;
    }
    VideoShader *shader = d.manager->prepareMaterial(d.material); //TODO: print shader type name if changed. prepareMaterial(,sample_code, pp_code)
    shader->update(d.material);
    shader->program()->setUniformValue(shader->opacityLocation(), (GLfloat)1.0);
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    DYGL(glDrawArrays(d.geometry.mode(), 0, d.geometry.textureVertexCount()));
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();
}
Exemple #5
0
void GeometryRenderer::render()
{
    if (!g)
        return;
    if (g->indexCount() > 0) {
        DYGL(glDrawElements(g->primitive(), g->indexCount(), g->indexType(), g->indexData()));
    } else {
        DYGL(glDrawArrays(g->primitive(), 0, g->vertexCount()));
    }
}
Exemple #6
0
// TODO: set surface/device size here (viewport?)
void OpenGLVideo::setOpenGLContext(QOpenGLContext *ctx)
{
    DPTR_D(OpenGLVideo);
    if (d.ctx == ctx)
        return;
    d.resetGL(); //TODO: is it ok to destroygl resources in another context?
    d.ctx = ctx; // Qt4: set to null in resetGL()
    if (!ctx) {
        return;
    }
    if (d.material)
        delete d.material;
    d.material = new VideoMaterial();
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    d.manager = ctx->findChild<ShaderManager*>(QStringLiteral("__qtav_shader_manager"));
    QSizeF surfaceSize = QOpenGLContext::currentContext()->surface()->size();
#else
    QSizeF surfaceSize = QSizeF(ctx->device()->width(), ctx->device()->height());
#endif
    setProjectionMatrixToRect(QRectF(QPointF(), surfaceSize));
    if (d.manager)
        return;
    // TODO: what if ctx is delete?
    d.manager = new ShaderManager(ctx);
    d.manager->setObjectName(QStringLiteral("__qtav_shader_manager"));
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    QObject::connect(ctx, SIGNAL(aboutToBeDestroyed()), this, SLOT(resetGL()), Qt::DirectConnection); //direct?
#endif
    /// get gl info here because context is current(qt ensure it)
    //const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
    bool hasGLSL = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
    qDebug("OpenGL version: %d.%d  hasGLSL: %d", ctx->format().majorVersion(), ctx->format().minorVersion(), hasGLSL);
    static bool sInfo = true;
    if (sInfo) {
        sInfo = false;
        qDebug("GL_VERSION: %s", DYGL(glGetString(GL_VERSION)));
        qDebug("GL_VENDOR: %s", DYGL(glGetString(GL_VENDOR)));
        qDebug("GL_RENDERER: %s", DYGL(glGetString(GL_RENDERER)));
        qDebug("GL_SHADING_LANGUAGE_VERSION: %s", DYGL(glGetString(GL_SHADING_LANGUAGE_VERSION)));
        /// check here with current context can ensure the right result. If the first check is in VideoShader/VideoMaterial/decoder or somewhere else, the context can be null
        bool v = OpenGLHelper::isOpenGLES();
        qDebug("Is OpenGLES: %d", v);
        v = OpenGLHelper::isEGL();
        qDebug("Is EGL: %d", v);
        const int glsl_ver = OpenGLHelper::GLSLVersion();
        qDebug("GLSL version: %d", glsl_ver);
        v = OpenGLHelper::isPBOSupported();
        qDebug("Has PBO: %d", v);
        v = OpenGLHelper::has16BitTexture();
        qDebug("Has 16bit texture: %d", v);
        v = OpenGLHelper::hasRG();
        qDebug("Has RG texture: %d", v);
        qDebug() << ctx->format();
    }
}
Exemple #7
0
void GeometryRenderer::render()
{
    if (!g)
        return;
    bindBuffers();
    if (g->indexCount() > 0) {
        DYGL(glDrawElements(g->primitive(), g->indexCount(), g->indexType(), ibo.isCreated() ? NULL : g->indexData())); // null: data in vao or ibo. not null: data in memory
    } else {
        DYGL(glDrawArrays(g->primitive(), 0, g->vertexCount()));
    }
    unbindBuffers();
}
Exemple #8
0
int GLSLVersion()
{
    static int v = -1;
    if (v >= 0)
        return v;
    if (!QOpenGLContext::currentContext()) {
        qWarning("%s: current context is null", __FUNCTION__);
        return 0;
    }
    const char* vs = (const char*)DYGL(glGetString(GL_SHADING_LANGUAGE_VERSION));
    int major = 0, minor = 0;
    // es: "OpenGL ES GLSL ES 1.00 (ANGLE 2.1.99...)" can use ""%*[ a-zA-Z] %d.%d" in sscanf, desktop: "2.1"
    //QRegExp rx("(\\d+)\\.(\\d+)");
    if (strncmp(vs, "OpenGL ES GLSL ES ", 18) == 0)
        vs += 18;
    if (sscanf(vs, "%d.%d", &major, &minor) == 2) {
        v = major * 100 + minor;
    } else {
        qWarning("Failed to detect glsl version using GL_SHADING_LANGUAGE_VERSION!");
        v = 110;
        if (isOpenGLES())
            v = QOpenGLContext::currentContext()->format().majorVersion() >= 3 ? 300 : 100;
    }
    return v;
}
Exemple #9
0
void GeometryRenderer::render(Geometry *g)
{
    if (g->indexCount() > 0) {
        // IBO

    } else {
        DYGL(glDrawArrays(g->primitiveType(), 0, g->vertexCount()));
    }
}
Exemple #10
0
void OpenGLRendererBase::onInitializeGL()
{
    DPTR_D(OpenGLRendererBase);
    //makeCurrent();
#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
    initializeOpenGLFunctions();
#endif
    QOpenGLContext *ctx = const_cast<QOpenGLContext*>(QOpenGLContext::currentContext()); //qt4 returns const
    d.glv.setOpenGLContext(ctx);
    //const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
    bool hasGLSL = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
    qDebug("OpenGL version: %d.%d  hasGLSL: %d", ctx->format().majorVersion(), ctx->format().minorVersion(), hasGLSL);  
    static bool sInfo = true;
    if (sInfo) {
        sInfo = false;
        qDebug("GL_VERSION: %s", DYGL(glGetString(GL_VERSION)));
        qDebug("GL_VENDOR: %s", DYGL(glGetString(GL_VENDOR)));
        qDebug("GL_RENDERER: %s", DYGL(glGetString(GL_RENDERER)));
        qDebug("GL_SHADING_LANGUAGE_VERSION: %s", DYGL(glGetString(GL_SHADING_LANGUAGE_VERSION)));
    }
}
Exemple #11
0
void OpenGLVideo::setProjectionMatrixToRect(const QRectF &v)
{
    DPTR_D(OpenGLVideo);
    d.rect = v;
    d.matrix.setToIdentity();
    d.matrix.ortho(v);
    // Mirrored relative to the usual Qt coordinate system with origin in the top left corner.
    //mirrored = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0) > 0;
    d.update_geo = true; // even true for target_rect != d.rect
    if (d.ctx && d.ctx == QOpenGLContext::currentContext()) {
        DYGL(glViewport(d.rect.x(), d.rect.y(), d.rect.width(), d.rect.height()));
    }
}
Exemple #12
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    VideoShader *shader = d.manager->prepareMaterial(d.material);
    shader->update(d.material);
    shader->program()->setUniformValue(shader->opacityLocation(), (GLfloat)1.0);
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    DYGL(glDrawArrays(d.geometry.mode(), 0, d.geometry.textureVertexCount()));
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();
}
bool GLInteropResource::unmap(GLuint tex)
{
    Q_UNUSED(tex);
    if (!interop_obj || !interop_dev)
        return false;
    DYGL(glBindTexture(GL_TEXTURE_2D, 0));
    WGL_ENSURE(wgl->DXUnlockObjectsNV(interop_dev, 1, &interop_obj), false);
    WGL_WARN(wgl->DXUnregisterObjectNV(interop_dev, interop_obj));
    // interop operations end
    WGL_WARN(wgl->DXCloseDeviceNV(interop_dev));
    interop_obj = NULL;
    interop_dev = NULL;
    return true;
}
Exemple #14
0
bool test_gl_param(const gl_param_t& gp, bool* has_16 = 0)
{
    if (!QOpenGLContext::currentContext()) {
        qWarning("%s: current context is null", __FUNCTION__);
        return false;
    }
    GLuint tex;
    DYGL(glGenTextures(1, &tex));
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    DYGL(glTexImage2D(GL_TEXTURE_2D, 0, gp.internal_format, 64, 64, 0, gp.format, gp.type, NULL));
    GLint param = 0;
    //GL_PROXY_TEXTURE_2D and no glGenTextures?
#ifndef GL_TEXTURE_INTERNAL_FORMAT //only in desktop
#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
#endif
    OpenGLHelper::glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &param);
    // TODO: check glGetError()?
    if (param != gp.internal_format) {
        qDebug("Do not support texture internal format: %#x", gp.internal_format);
        DYGL(glDeleteTextures(1, &tex));
        return false;
    }
    if (!has_16) {
        DYGL(glDeleteTextures(1, &tex));
        return true;
    }
    *has_16 = false;
    GLenum pname = 0;
#ifndef GL_TEXTURE_RED_SIZE
#define GL_TEXTURE_RED_SIZE 0x805C
#endif
#ifndef GL_TEXTURE_LUMINANCE_SIZE
#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
#endif
    switch (gp.format) {
    case GL_RED:
        pname = GL_TEXTURE_RED_SIZE;
        break;
    case GL_LUMINANCE:
        pname = GL_TEXTURE_LUMINANCE_SIZE;
        break;
    }
    param = 0;
    if (pname)
        OpenGLHelper::glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, pname, &param);
    if (param) {
        qDebug("16 bit texture depth: %d.\n", (int)param);
        *has_16 = (int)param == 16;
    }
    DYGL(glDeleteTextures(1, &tex));
    return true;
}
bool GLInteropResource::map(IDirect3DSurface9 *surface, GLuint tex, int w, int h, int)
{
    if (!ensureResource(w, h, tex)) {
        releaseDX();
        return false;
    }
    // open/close and register/unregster in every map/unmap to ensure called in current context and avoid crash (tested on intel driver)
    // interop operations begin
    WGL_ENSURE((interop_dev = wgl->DXOpenDeviceNV(d3ddev)) != NULL, false);
    // call in ensureResource or in map?
    WGL_ENSURE((interop_obj = wgl->DXRegisterObjectNV(interop_dev, dx_surface, tex, GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV)) != NULL, false);
    // prepare dx resources for gl
    const RECT src = { 0, 0, w, h};
    DX_ENSURE_OK(d3ddev->StretchRect(surface, &src, dx_surface, NULL, D3DTEXF_NONE), false);
    // lock dx resources
    WGL_ENSURE(wgl->DXLockObjectsNV(interop_dev, 1, &interop_obj), false);
    WGL_ENSURE(wgl->DXObjectAccessNV(interop_obj, WGL_ACCESS_READ_ONLY_NV), false);
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    return true;
}
Exemple #16
0
void OpenGLVideo::fill(const QColor &color)
{
    DYGL(glClearColor(color.red(), color.green(), color.blue(), color.alpha()));
    DYGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
}