Пример #1
1
EGLSurface EGLDisplayOpenVG::createPbufferSurface(const IntSize& size, const EGLConfig& config, EGLint* errorCode)
{
    const EGLint attribList[] = {
        EGL_WIDTH, size.width(),
        EGL_HEIGHT, size.height(),
        EGL_NONE
    };
    EGLSurface surface = eglCreatePbufferSurface(m_display, config, attribList);

    if (errorCode)
        *errorCode = eglGetError();
    else
        ASSERT_EGL_NO_ERROR();

    if (surface == EGL_NO_SURFACE)
        return EGL_NO_SURFACE;

    EGLint surfaceConfigId;
    EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
    ASSERT(success == EGL_TRUE);
    ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

    ASSERT(!m_surfaceConfigIds.contains(surface));
    m_surfaceConfigIds.set(surface, surfaceConfigId);
    return surface;
}
FontPlatformDataStaticPrivate::FontPlatformDataStaticPrivate()
{
    m_engine = Olympia::Platform::Text::engine();
    ASSERT(m_engine);

    Olympia::Platform::Text::NativeGraphicsDisplay display;
#if PLATFORM(EGL)
    ASSERT_EGL_NO_ERROR();
    EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::current();
    display = static_cast<Olympia::Platform::Text::NativeGraphicsDisplay>(displayManager->display());
#endif
    Olympia::Platform::Text::ReturnCode error;
    m_context = m_engine->createGraphicsContext(error, Olympia::Platform::Text::OpenVGGraphicsContext, display);
    ASSERT(m_context);
    ASSERT(!error);

#if PLATFORM(EGL)
    ASSERT_EGL_NO_ERROR();
    SurfaceOpenVG* sharedSurface = displayManager->sharedPlatformSurface();
    m_context->setDisplay(static_cast<Olympia::Platform::Text::NativeGraphicsDisplay>(sharedSurface->eglDisplay()));
    m_context->setSurface(static_cast<Olympia::Platform::Text::NativeGraphicsSurface>(sharedSurface->eglSurface()));
    m_context->setContext(static_cast<Olympia::Platform::Text::NativeGraphicsContext>(sharedSurface->eglContext()));
    ASSERT_EGL_NO_ERROR();
#endif
}
Пример #3
0
void SurfaceOpenVG::makeCurrent(MakeCurrentMode mode)
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();
    EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
    ASSERT_EGL_NO_ERROR();

    if (currentSurface != m_eglSurface) {
        // Save other context before switching over.
        if (s_currentPainter && mode != DontSaveOrApplyPainterState
            && s_currentPainter->currentSurface()->m_eglSurface == currentSurface)
            s_currentPainter->save(PainterOpenVG::KeepCurrentState);

        eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
        ASSERT_EGL_NO_ERROR();
        s_currentPainter = 0;
    }
#endif

    if (m_activePainter && mode == ApplyPainterStateOnSurfaceSwitch
        && s_currentPainter != m_activePainter) {
        m_activePainter->applyState();
        s_currentPainter = m_activePainter;
    }
}
Пример #4
0
void SurfaceOpenVG::makeCompatibleCurrent()
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();
    EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
    ASSERT_EGL_NO_ERROR();

    if (currentSurface == m_eglSurface) {
        if (m_activePainter && s_currentPainter != m_activePainter) {
            m_activePainter->applyState();
            s_currentPainter = m_activePainter;
        }
    } else if (!EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) {
        // Save other context before switching over.
        if (s_currentPainter && s_currentPainter->currentSurface()->m_eglSurface == currentSurface)
            s_currentPainter->save(PainterOpenVG::KeepCurrentState);

        eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
        ASSERT_EGL_NO_ERROR();
        s_currentPainter = 0;
    }
    // else: surfaces compatible, no need to switch contexts
#endif
}
Пример #5
0
void SurfaceOpenVG::makeResourceCreationContextCurrent()
{
#if PLATFORM(EGL)
    ASSERT(m_eglContext != EGL_NO_CONTEXT);

    SurfaceOpenVG* shared = sharedSurface();

    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();
    EGLContext currentContext = eglGetCurrentContext();
    ASSERT_EGL_NO_ERROR();

    // The shared surface might not be current, but the shared context is.
    // A proper OpenVG implementation stores all resources in the context,
    // and none in the surface, so we don't need to do anything here.
    if (currentContext == shared->m_eglContext)
        return;

    // The shared surface is not usually used for any productive work,
    // any other surface (i.e. this) is more likely to be painted on.
    if (m_eglContext == shared->m_eglContext) {
        makeCurrent(DontApplyPainterState);
        return;
    }

    shared->makeCurrent(DontApplyPainterState);
#endif
}
Пример #6
0
SurfaceOpenVG::SurfaceOpenVG(EGLClientBuffer buffer, EGLenum bufferType, const EGLDisplay& display, EGLConfig* confPtr, EGLint* errorCode)
    : m_activePainter(0)
    , m_eglDisplay(display)
    , m_eglSurface(EGL_NO_SURFACE)
    , m_eglContext(EGL_NO_CONTEXT)
{
    ASSERT(m_eglDisplay != EGL_NO_DISPLAY);

    EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::forDisplay(m_eglDisplay);
    EGLConfig config = confPtr ? (*confPtr) : displayManager->defaultPbufferConfig();
    m_eglSurface = displayManager->createPbufferFromClientBuffer(buffer, bufferType, config, errorCode);

    if (m_eglSurface == EGL_NO_SURFACE)
        return;

    EGLint width = 0, height = 0;
    eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &width);
    ASSERT_EGL_NO_ERROR();
    eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &height);
    ASSERT_EGL_NO_ERROR();
    m_size = IntSize(width, height);

    m_eglContext = displayManager->contextForSurface(m_eglSurface);
    EGLDisplayOpenVG::registerPlatformSurface(this);
}
void EGLDisplayOpenVG::removeSurface(const EGLSurface& surface, bool destroySurface)
{
    ASSERT(surface != EGL_NO_SURFACE);

#if PLATFORM(OLYMPIA)
    if (destroySurface) {
        // Work around a bug in our EGL implementation where the VGImage
        // referenced by eglCreatePbufferFromClientBuffer is not released
        // when destroying the context, RIM Bug #1591.
        // The context that created the VGImage needs to be current for
        // it to be released.
        sharedPlatformSurface()->makeResourceCreationContextCurrent();
    } else
#endif
    if (eglGetCurrentSurface(EGL_DRAW) == surface) {
        eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        ASSERT_EGL_NO_ERROR();
    }

    // Destroy the context associated to the surface, if we already created one.
    if (m_surfaceConfigIds.contains(surface)) {
        EGLint surfaceConfigId = m_surfaceConfigIds.take(surface); // take = get and remove
        bool isContextReferenced = false;

        if (m_compatibleConfigIds.contains(surfaceConfigId))
            surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId);

        HashMap<EGLSurface, EGLint>::iterator end = m_surfaceConfigIds.end();

        // ...but only if there's no other surfaces associated to that context.
        for (HashMap<EGLSurface, EGLint>::iterator it = m_surfaceConfigIds.begin(); it != end; ++it) {
            if ((*it).second == surfaceConfigId) {
                isContextReferenced = true;
                break;
            }
        }
        if (!isContextReferenced && m_contexts.contains(surfaceConfigId)) {
            EGLContext context = m_contexts.take(surfaceConfigId);
            eglDestroyContext(m_display, context);
            ASSERT_EGL_NO_ERROR();
        }
    }

    m_platformSurfaces.remove(surface);

    HashMap<EGLNativeWindowType, EGLSurface>::iterator end = m_windowSurfaces.end();
    for (HashMap<EGLNativeWindowType, EGLSurface>::iterator it = m_windowSurfaces.begin(); it != end; ++it) {
        if ((*it).second == surface) {
            m_windowSurfaces.remove(it);
            break;
        }
    }

    if (destroySurface) {
        eglDestroySurface(m_display, surface);
        ASSERT_EGL_NO_ERROR();
    }
}
Пример #8
0
SurfaceOpenVG* SurfaceOpenVG::adoptExistingSurface(const EGLDisplay& display, const EGLSurface& surface, const EGLContext& context, SurfaceOwnership ownership, EGLint surfaceType)
{
    SurfaceOpenVG* s = new SurfaceOpenVG;
    s->m_eglDisplay = display;
    s->m_eglSurface = surface;
    s->m_eglContext = context;
    s->m_doesOwnSurface = ownership == TakeSurfaceOwnership;

    // The surface size can change for windows, but not for pbuffer or
    // pixmap surfaces. If we don't know whether we're a window or not,
    // we can check the config and hope it only supports a specific type
    // of surface. (If we don't know that as well, we can't cache the size.)
    // Unfortunately, EGL 1.4 doesn't allow for any way to retrieve the
    // surface type, so this is the best we can do here.
    if (surfaceType & EGL_WINDOW_BIT && surfaceType & (EGL_PBUFFER_BIT | EGL_PIXMAP_BIT)) {
        // Retrieve the same EGL config for context creation that was used to
        // create the the EGL surface, and see if we can extract the size.
        EGLint surfaceConfigId;
        EGLBoolean success = eglQuerySurface(display, surface, EGL_CONFIG_ID, &surfaceConfigId);
        ASSERT(success == EGL_TRUE);
        ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

        EGLConfig config;
        EGLint numConfigs;

        const EGLint configAttribs[] = {
            EGL_CONFIG_ID, surfaceConfigId,
            EGL_NONE
        };
        eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
        ASSERT_EGL_NO_ERROR();
        ASSERT(numConfigs == 1);

        EGLint configSurfaceType;
        success = eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &configSurfaceType);
        ASSERT(success == EGL_TRUE);
        ASSERT(surfaceType != EGL_BAD_ATTRIBUTE);

        surfaceType &= configSurfaceType;
    }

    // Hopefully we now know whether we've got a window or not,
    // so we can cache the surface size.
    if (!(surfaceType & EGL_WINDOW_BIT)) {
        EGLint len = 0;
        eglQuerySurface(display, surface, EGL_WIDTH, &len);
        ASSERT_EGL_NO_ERROR();
        s->m_size.setWidth(len);
        eglQuerySurface(display, surface, EGL_HEIGHT, &len);
        ASSERT_EGL_NO_ERROR();
        s->m_size.setHeight(len);
    }

    EGLDisplayOpenVG::registerPlatformSurface(s);
    return s;
}
Пример #9
0
EGLDisplayOpenVG::~EGLDisplayOpenVG()
{
    eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    ASSERT_EGL_NO_ERROR();

    delete m_sharedPlatformSurface;

    HashMap<EGLSurface, EGLint>::const_iterator end = m_surfaceConfigIds.end();
    for (HashMap<EGLSurface, EGLint>::const_iterator it = m_surfaceConfigIds.begin(); it != end; ++it)
        destroySurface((*it).first);

    eglTerminate(m_display);
    ASSERT_EGL_NO_ERROR();
}
Пример #10
0
EGLConfig EGLDisplayOpenVG::defaultWindowConfig()
{
    EGLConfig config;
    EGLint numConfigs;

    // Hopefully the client will have set the window config of its choice
    // by now - if not, use a 32-bit generic one as default.
    if (!m_windowConfigId) {
        static const EGLint configAttribs[] = {
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_ALPHA_MASK_SIZE, 1,
            EGL_LUMINANCE_SIZE, EGL_DONT_CARE,
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
            EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
            EGL_NONE
        };
        eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
    } else {
        const EGLint configAttribs[] = {
            EGL_CONFIG_ID, m_windowConfigId,
            EGL_NONE
        };
        eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
    }

    ASSERT_EGL_NO_ERROR();
    ASSERT(numConfigs == 1);
    return config;
}
Пример #11
0
void EGLDisplayOpenVG::destroySurface(const EGLSurface& surface)
{
    ASSERT(surface != EGL_NO_SURFACE);

    if (eglGetCurrentSurface(EGL_DRAW) == surface) {
        eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        ASSERT_EGL_NO_ERROR();
    }

    // Destroy the context associated to the surface, if we already created one.
    if (m_surfaceConfigIds.contains(surface)) {
        EGLint surfaceConfigId = m_surfaceConfigIds.take(surface); // take = get and remove
        bool isContextReferenced = false;

        if (m_compatibleConfigIds.contains(surfaceConfigId))
            surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId);

        HashMap<EGLSurface, EGLint>::iterator end = m_surfaceConfigIds.end();

        // ...but only if there's no other surfaces associated to that context.
        for (HashMap<EGLSurface, EGLint>::iterator it = m_surfaceConfigIds.begin(); it != end; ++it) {
            if ((*it).second == surfaceConfigId) {
                isContextReferenced = true;
                break;
            }
        }
        if (!isContextReferenced && m_contexts.contains(surfaceConfigId)) {
            EGLContext context = m_contexts.take(surfaceConfigId);
            eglDestroyContext(m_display, context);
            ASSERT_EGL_NO_ERROR();
        }
    }

    m_platformSurfaces.remove(surface);

    HashMap<EGLNativeWindowType, EGLSurface>::iterator end = m_windowSurfaces.end();
    for (HashMap<EGLNativeWindowType, EGLSurface>::iterator it = m_windowSurfaces.begin(); it != end; ++it) {
        if ((*it).second == surface) {
            m_windowSurfaces.remove(it);
            break;
        }
    }

    eglDestroySurface(m_display, surface);
    ASSERT_EGL_NO_ERROR();
}
Пример #12
0
void SurfaceOpenVG::flush()
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    eglSwapBuffers(m_eglDisplay, m_eglSurface);
    ASSERT_EGL_NO_ERROR();
#endif
}
Пример #13
0
EGLDisplayOpenVG::EGLDisplayOpenVG(const EGLDisplay& display)
    : m_display(display)
    , m_sharedPlatformSurface(0)
    , m_pbufferConfigId(0)
    , m_windowConfigId(0)
{
    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();
}
Пример #14
0
SurfaceGL2D::SurfaceGL2D(QPainter* painter)
{
    m_qpainter = painter;
    eglBindAPI(EGL_OPENGL_ES_API);
    ASSERT_EGL_NO_ERROR();
    m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(m_eglDisplay, 0, 0);
    ASSERT_EGL_NO_ERROR();
    getEGLConfig(&m_eglConfig, PbufferSurface);
    const EGLint attribList[] = {
        EGL_WIDTH, m_qpainter->device()->width(),
        EGL_HEIGHT, m_qpainter->device()->height(),
        EGL_NONE
    };
    ASSERT_EGL_NO_ERROR();
    m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attribList);
    ASSERT_EGL_NO_ERROR();
}
Пример #15
0
EGLDisplayOpenVG* EGLDisplayOpenVG::current()
{
    if (!s_current) {
        EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        eglInitialize(display, 0, 0);
        ASSERT_EGL_NO_ERROR();

        s_current = EGLDisplayOpenVG::forDisplay(display);
    }
    return s_current;
}
EGLDisplayOpenVG::~EGLDisplayOpenVG()
{
    eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    ASSERT_EGL_NO_ERROR();

    HashMap<EGLSurface, SurfaceOpenVG*>::const_iterator end = m_platformSurfaces.end();
    for (HashMap<EGLSurface, SurfaceOpenVG*>::const_iterator it = m_platformSurfaces.begin(); it != end; ++it)
        (*it).second->detach();

    delete m_sharedPlatformSurface;
}
Пример #17
0
void SurfaceOpenVG::makeCurrent(MakeCurrentMode mode)
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();
    EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
    ASSERT_EGL_NO_ERROR();

    if (currentSurface != m_eglSurface) {
        eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
        ASSERT_EGL_NO_ERROR();
        s_currentPainter = 0;
    }
#endif

    if (m_activePainter && mode == ApplyPainterStateOnSurfaceSwitch
        && s_currentPainter != m_activePainter) {
        m_activePainter->applyState();
        s_currentPainter = m_activePainter;
    }
}
Пример #18
0
int SurfaceOpenVG::width() const
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    EGLint width;
    eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &width);
    ASSERT_EGL_NO_ERROR();
    return width;
#else
    ASSERT_NOT_REACHED();
    return 0;
#endif
}
Пример #19
0
int SurfaceOpenVG::height() const
{
#if PLATFORM(EGL)
    ASSERT(m_eglSurface != EGL_NO_SURFACE);

    EGLint height;
    eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &height);
    ASSERT_EGL_NO_ERROR();
    return height;
#else
    ASSERT_NOT_REACHED();
    return 0;
#endif
}
Пример #20
0
EGLSurface EGLDisplayOpenVG::surfaceForWindow(EGLNativeWindowType wId, const EGLConfig& config)
{
    if (m_windowSurfaces.contains(wId))
        return m_windowSurfaces.get(wId);

    EGLSurface surface = eglCreateWindowSurface(m_display, config, wId, 0);
    ASSERT_EGL_NO_ERROR();

    EGLint surfaceConfigId;
    EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
    ASSERT(success == EGL_TRUE);
    ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

    ASSERT(!m_surfaceConfigIds.contains(surface));
    m_surfaceConfigIds.set(surface, surfaceConfigId);
    return surface;
}
SurfaceOpenVG* EGLDisplayOpenVG::sharedPlatformSurface()
{
    if (!m_sharedPlatformSurface) {
        // The shared surface doesn't need to be drawn on, it just exists so
        // that we can always make the shared context current (which in turn is
        // the owner of long-living resources such as images, paths and fonts).
        // We'll just make the shared surface as small as possible: 1x1 pixel.
        EGLConfig config = defaultPbufferConfig();
        EGLSurface surface = createPbufferSurface(IntSize(1, 1), config);

        EGLContext context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, 0);
        ASSERT_EGL_NO_ERROR();
        m_contexts.set(m_surfaceConfigIds.get(surface), context);

        m_sharedPlatformSurface = SurfaceOpenVG::adoptExistingSurface(
            m_display, surface, context, SurfaceOpenVG::TakeSurfaceOwnership, EGL_PBUFFER_BIT);
    }
    return m_sharedPlatformSurface;
}
Пример #22
0
SurfaceOpenVG* EGLDisplayOpenVG::sharedPlatformSurface()
{
    if (!m_sharedPlatformSurface) {
        // The shared surface doesn't need to be drawn on, it just exists so
        // that we can always make the shared context current (which in turn is
        // the owner of long-living resources such as images, paths and fonts).
        // We'll just make the shared surface as small as possible: 1x1 pixel.
        EGLConfig config = defaultPbufferConfig();
        EGLSurface surface = createPbufferSurface(IntSize(1, 1), config);

        EGLContext context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, 0);
        ASSERT_EGL_NO_ERROR();
        m_contexts.set(m_surfaceConfigIds.get(surface), context);

        m_sharedPlatformSurface = new SurfaceOpenVG;
        m_sharedPlatformSurface->m_eglDisplay = m_display;
        m_sharedPlatformSurface->m_eglSurface = surface;
        m_sharedPlatformSurface->m_eglContext = context;
        m_platformSurfaces.set(surface, m_sharedPlatformSurface); // a.k.a. registerPlatformSurface()
    }
    return m_sharedPlatformSurface;
}
Пример #23
0
EGLSurface EGLDisplayOpenVG::createPbufferFromClientBuffer(
    EGLClientBuffer clientBuffer, EGLenum bufferType, const EGLConfig& config, EGLint* errorCode)
{
    EGLSurface surface = eglCreatePbufferFromClientBuffer(m_display,
        bufferType, clientBuffer, config, 0 /* attribList */);

    if (errorCode)
        *errorCode = eglGetError();
    else
        ASSERT_EGL_NO_ERROR();

    if (surface == EGL_NO_SURFACE)
        return EGL_NO_SURFACE;

    EGLint surfaceConfigId;
    EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
    ASSERT(success == EGL_TRUE);
    ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

    ASSERT(!m_surfaceConfigIds.contains(surface));
    m_surfaceConfigIds.set(surface, surfaceConfigId);
    return surface;
}
EGLSurface EGLDisplayOpenVG::createPbufferSurface(const IntSize& size, const EGLConfig& config, EGLint* errorCode)
{
    const EGLint attribList[] = {
        EGL_WIDTH, size.width(),
        EGL_HEIGHT, size.height(),

#ifdef WEBKIT_EGL_SURFACE_DEFAULT_COLORSPACE
        EGL_COLORSPACE, WEBKIT_EGL_SURFACE_DEFAULT_COLORSPACE,
#endif

        // FIXME: make it possible to change alpha format with a setting, as its impact is implementation-specific.
#ifdef EGL_VG_ALPHA_FORMAT // EGL 1.3 and later
        EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE,
#else // EGL 1.2
        EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE,
#endif
        EGL_NONE
    };
    EGLSurface surface = eglCreatePbufferSurface(m_display, config, attribList);

    if (errorCode)
        *errorCode = eglGetError();
    else
        ASSERT_EGL_NO_ERROR();

    if (surface == EGL_NO_SURFACE)
        return EGL_NO_SURFACE;

    EGLint surfaceConfigId;
    EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
    ASSERT(success == EGL_TRUE);
    ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

    ASSERT(!m_surfaceConfigIds.contains(surface));
    m_surfaceConfigIds.set(surface, surfaceConfigId);
    return surface;
}
Пример #25
0
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
    const FontPlatformData& fontPlatformData = primaryFont()->platformData();
    const float scaleFactor = fontPlatformData.scaleFactor();
    Olympia::Platform::Text::Font* font = fontPlatformData.font(); // FIXME: use fallback fonts as well?
    Olympia::Platform::Text::DrawParam drawParam;

    String sanitized = setupTextDrawing(this, run, &drawParam);
    adjustOffsetsForTextDrawing(run, from, to);

    SurfaceOpenVG* surface = context->platformContext();
    surface->makeCurrent();

    // Before passing control to Text API, make sure we're ok ourselves.
    ASSERT_VG_NO_ERROR();

    PainterOpenVG* painter = surface->activePainter();
    painter->save();
    painter->setStateModified(PainterOpenVG::AllStateCategories);

    Olympia::Platform::Text::GraphicsContext* textContext = FontPlatformData::textGraphicsContext();

#if PLATFORM(EGL)
    textContext->setDisplay(static_cast<Olympia::Platform::Text::NativeGraphicsDisplay>(surface->eglDisplay()));
    textContext->setSurface(static_cast<Olympia::Platform::Text::NativeGraphicsSurface>(surface->eglSurface()));
    textContext->setContext(static_cast<Olympia::Platform::Text::NativeGraphicsContext>(surface->eglContext()));
    ASSERT_EGL_NO_ERROR();
#endif

    if (painter->textDrawingMode() & cTextClip)
        return; // unsupported for every port except CG at the time of writing
    if (!(painter->textDrawingMode() & cTextFill))
        painter->setFillColor(Color::transparent);
    if (!(painter->textDrawingMode() & cTextStroke))
        painter->setStrokeStyle(NoStroke);

    if (from > 0 || to < sanitized.length()) {
        // Clip to the from-to region. We need to draw the full text
        // (and clip) because characters might change appearance when
        // connected to other characters.
        double fromX;
        FontPlatformData::engine()->textPosToX(from, fromX, *font,
            sanitized.characters(), sanitized.length(), drawParam);
        ASSERT_VG_NO_ERROR();
        fromX *= scaleFactor;

        double toX;
        FontPlatformData::engine()->textPosToX(to, toX, *font,
            sanitized.characters(), sanitized.length(), drawParam);
        ASSERT_VG_NO_ERROR();
        toX *= scaleFactor;

        // FIXME: Some glyphs can be higher than primary font's height.
        // We multiply ascent and descent by 4 so the clip rect will be high
        // enough for all glyphs we know. This is safe because we only apply
        // the clip rect when drawing partial strings, and we are only interested
        // in horizontal clip range.
        const float y = point.y() - primaryFont()->ascent() * 4;
        const float height = (primaryFont()->ascent() + primaryFont()->descent()) * 4;
        FloatRect clipRect = (toX > fromX)
            ? FloatRect(point.x() + fromX, y, toX - fromX, height)
            : FloatRect(point.x() + toX, y, fromX - toX, height);

        painter->clipRect(clipRect, PainterOpenVG::IntersectClip);
    }

    AffineTransform transformation = painter->transformation();
    transformation.translate(point.x(), point.y());
    FloatPoint currentTranslation(transformation.e(), transformation.f());
    transformation.setE(0);
    transformation.setF(0);
    transformation.scale(scaleFactor);
    transformation.setE(roundf(currentTranslation.x()));
    transformation.setF(roundf(currentTranslation.y()));
    painter->setTransformation(transformation);

    if (painter->shadowEnabled()) {
        painter->beginDrawShadow();
        FontPlatformData::engine()->drawText(textContext, *font,
            sanitized.characters(), sanitized.length(), 0, 0,
            0 /* no wrap */, &drawParam, 0 /* returned metrics */);
        painter->endDrawShadow();
    }

    FontPlatformData::engine()->drawText(textContext, *font,
        sanitized.characters(), sanitized.length(), 0, 0,
        0 /* no wrap */, &drawParam, 0 /* returned metrics */);

#if PLATFORM(EGL)
    SurfaceOpenVG* sharedSurface = surface->sharedSurface();
    textContext->setDisplay(static_cast<Olympia::Platform::Text::NativeGraphicsDisplay>(sharedSurface->eglDisplay()));
    textContext->setSurface(static_cast<Olympia::Platform::Text::NativeGraphicsSurface>(sharedSurface->eglSurface()));
    textContext->setContext(static_cast<Olympia::Platform::Text::NativeGraphicsContext>(sharedSurface->eglContext()));
    ASSERT_EGL_NO_ERROR();
#endif

    // Let's make sure Text API didn't cause any troubles.
    ASSERT_VG_NO_ERROR();
    painter->restore();
}
Пример #26
0
EGLContext EGLDisplayOpenVG::contextForSurface(const EGLSurface& surface)
{
    ASSERT(surface != EGL_NO_SURFACE);

    if (m_platformSurfaces.contains(surface))
        return m_platformSurfaces.get(surface)->eglContext();

    eglBindAPI(EGL_OPENVG_API);
    ASSERT_EGL_NO_ERROR();

    EGLint surfaceConfigId;

    if (m_surfaceConfigIds.contains(surface))
        surfaceConfigId = m_surfaceConfigIds.get(surface);
    else {
        // Retrieve the same EGL config for context creation that was used to
        // create the the EGL surface.
        EGLBoolean success = eglQuerySurface(m_display, surface, EGL_CONFIG_ID, &surfaceConfigId);
        ASSERT(success == EGL_TRUE);
        ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);

        m_surfaceConfigIds.set(surface, surfaceConfigId);
    }

    if (m_compatibleConfigIds.contains(surfaceConfigId))
        surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId);

    if (m_contexts.contains(surfaceConfigId))
        return m_contexts.get(surfaceConfigId);

    if (!m_sharedPlatformSurface) // shared context has not been created yet
        sharedPlatformSurface(); // creates the shared surface & context

    EGLDisplay currentDisplay = eglGetCurrentDisplay();
    EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
    EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
    EGLContext currentContext = eglGetCurrentContext();

    // Before creating a new context, let's try whether an existing one
    // is compatible with the surface. EGL doesn't give us a different way
    // to check context/surface compatibility than trying it out, so let's
    // do just that.
    HashMap<EGLint, EGLContext>::iterator end = m_contexts.end();

    for (HashMap<EGLint, EGLContext>::iterator it = m_contexts.begin(); it != end; ++it) {
        eglMakeCurrent(m_display, surface, surface, (*it).second);
        if (eglGetError() == EGL_SUCCESS) {
            // Restore previous surface/context.
            if (currentContext != EGL_NO_CONTEXT) {
                eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext);
                ASSERT_EGL_NO_ERROR();
            }
            // Cool, surface is compatible to one of our existing contexts.
            m_compatibleConfigIds.set(surfaceConfigId, (*it).first);
            return (*it).second;
        }
    }
    // Restore previous surface/context.
    if (currentContext != EGL_NO_CONTEXT) {
        eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext);
        ASSERT_EGL_NO_ERROR();
    }

    EGLConfig config;
    EGLint numConfigs;

    const EGLint configAttribs[] = {
        EGL_CONFIG_ID, surfaceConfigId,
        EGL_NONE
    };

    eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
    ASSERT_EGL_NO_ERROR();
    ASSERT(numConfigs == 1);

    // We share all of the images and paths amongst the different contexts,
    // so that they can be used in all of them. Resources that are created
    // while m_sharedPlatformSurface->context() is current will be
    // accessible from all other contexts, but are not restricted to the
    // lifetime of those contexts.
    EGLContext context = eglCreateContext(m_display, config, m_sharedPlatformSurface->eglContext(), 0);
    ASSERT_EGL_NO_ERROR();

    ASSERT(!m_contexts.contains(surfaceConfigId));
    m_contexts.set(surfaceConfigId, context);
    return context;
}