示例#1
0
String GraphicsContext3DInternal::getShaderInfoLog(Platform3DObject shader)
{
    LOGWEBGL("getShaderInfoLog()");
    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);

    if (result == m_shaderSourceMap.end()) {
        LOGWEBGL("  shader not found");
        return "";
    }

    ShaderSourceEntry entry = result->second;

    if (entry.isValid) {
        LOGWEBGL("  validated shader, retrieve OpenGL log");
        GLuint shaderID = shader;
        GLint logLength;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
        if (!logLength)
            return "";

        char* log = 0;
        if ((log = (char *)fastMalloc(logLength * sizeof(char))) == 0)
            return "";
        GLsizei returnedLogLength;
        glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log);
        String res = String(log, returnedLogLength);
        fastFree(log);

        return res;
    }
    else {
        LOGWEBGL("  non-validated shader, use ANGLE log");
        return entry.log;
    }
}
示例#2
0
bool GraphicsContext3DInternal::lockFrontBuffer(T& image, SkRect& rect)
{
    LOGWEBGL("GraphicsContext3DInternal::lockFrontBuffer()");
    MutexLocker lock(m_fboMutex);
    FBO* fbo = m_frontFBO;

    if (!fbo || !fbo->image()) {
        LOGWEBGL("-GraphicsContext3DInternal::lockFrontBuffer(), fbo = %p", fbo);
        return false;
    }

    fbo->setLocked(true);
    image = (T)(fbo->image());

    RenderObject* renderer = m_canvas->renderer();
    if (renderer && renderer->isBox()) {
        RenderBox* box = (RenderBox*)renderer;
        rect.setXYWH(box->borderLeft() + box->paddingLeft(),
                     box->borderTop() + box->paddingTop(),
                     box->contentWidth(),
                     box->contentHeight());
    }

    return true;
}
示例#3
0
PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData()
{
    LOGWEBGL("paintRenderingResultsToImageData()");

    // Reading premultiplied alpha would involve unpremultiplying, which is lossy.
    if (m_attrs.premultipliedAlpha)
        return 0;

    RefPtr<ImageData> imageData = ImageData::create(IntSize(m_width, m_height));
    unsigned char* pixels = imageData->data()->data()->data();
    //[CAPPFIX_WEB_WEBGL] - better performance
    if (m_canvasDirty) {
        glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    } else {
        LOGWEBGL("paintRenderingResultsToImageData() >>> from clean canvas, so read the back buffer >>> m_canvasDirty:%d", m_canvasDirty);
        unsigned char* bits;
        MutexLocker lock(m_fboMutex);

        FBO* fbo = m_frontFBO;
        if (!fbo)
            return NULL;

        if (fbo->lockGraphicBuffer((void**)&bits)) {
            memcpy(pixels, bits, (m_width * m_height * 4));
            fbo->unlockGraphicBuffer();
        }
    }
    LOGWEBGL("-paintRenderingResultsToImageData()");
    // [CAPPFIX_WEB_WEBGL_END]
    return imageData;
}
示例#4
0
void GraphicsContext3DInternal::runSyncThread()
{
    LOGWEBGL("SyncThread: starting");
    FBO* fbo = 0;

    MutexLocker lock(m_threadMutex);
    m_threadState = THREAD_STATE_RUN;
    // Signal to creator that we are up and running
    m_threadCondition.broadcast();

    while (m_threadState == THREAD_STATE_RUN) {
        while (m_threadState == THREAD_STATE_RUN) {
            {
                MutexLocker lock(m_fboMutex);
                if (!m_queuedBuffers.isEmpty()) {
                    fbo = m_queuedBuffers.takeFirst();
                    break;
                }
            }
            m_threadCondition.wait(m_threadMutex);
        }
        LOGWEBGL("SyncThread: woke after waiting for FBO, fbo = %p", fbo);
        if (m_threadState != THREAD_STATE_RUN)
            break;

        //[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin
        if (m_needImproveUIResponseMode)
            glFinish();
        //[CAPPFIX_WEB_WEBGL_END]
        destroyEGLSync(fbo);

        {
            MutexLocker lock(m_fboMutex);
            m_preparedBuffers.append(fbo);
            LOGWEBGL("SyncThread: prepared buffer = %p", fbo);
            //[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin
            if (m_needImproveUIResponseMode) {
                // Wait at least one sec for buffer to get used.
                // This prevents the webkit thread running ahead of itself
                m_fboCondition.timedWait(m_fboMutex, currentTime() + 0.3);
            }
            //[CAPPFIX_WEB_WEBGL_END]
            updateFrontBuffer();
        }

        // Invalidate the canvas region
        if (m_postInvalidate) {
            JNIEnv* env = JSC::Bindings::getJNIEnv();
            env->CallVoidMethod(m_webView, m_postInvalidate);
        }
    }

    // Signal to calling thread that we have stopped
    m_threadState = THREAD_STATE_STOPPED;
    m_threadCondition.broadcast();
    LOGWEBGL("SyncThread: terminating");
}
示例#5
0
WebGLLayer::~WebGLLayer()
{
    LOGWEBGL("WebGLLayer::~WebGLLayer(), this = %p", this);
    for (int i = 0; i < 2; i++) {
        if (m_textures[i] != 0) {
            LOGWEBGL("glDeleteTextures(1, %d)", m_textures[i]);
            glDeleteTextures(1, &m_textures[i]);
            LOGWEBGL("glGetError() = %d", glGetError());
        }
    }
}
示例#6
0
bool WebGLLayer::drawGL(bool layerTilesDisabled)
{

    LOGWEBGL("WebGLLayer::drawGL() [+]");
    bool askScreenUpdate = false;

    askScreenUpdate |= LayerAndroid::drawGL(layerTilesDisabled);

    if (m_proxy.get()) {
        EGLImageKHR eglImage;
        int width;
        int height;
        SkRect localBounds;
        bool requestUpdate;
        bool locked = m_proxy->lockFrontBuffer(eglImage, width, height, localBounds, requestUpdate);
        if (locked) {
            GLuint texture;
            LOGWEBGL("WebGLLayer::drawGL(), this = %p, m_proxy = %p, eglImage = %d", this, m_proxy.get(), eglImage);
            if (m_eglImages[0] == eglImage) {
                texture = m_textures[0];
            }
            else if (m_eglImages[1] == eglImage) {
                texture = m_textures[1];
            }
            else {
                // New buffer
                int idx = 0;
                if (m_eglImages[idx] != 0)
                    idx++;
                if (m_eglImages[idx] != 0)
                    return false;
                m_eglImages[idx] = eglImage;
                m_textures[idx] = createTexture(eglImage, width, height);
                texture = m_textures[idx];
            }

            // Flip the y-coordinate
            TransformationMatrix transform = m_drawTransform;
            transform = transform.translate(0, 2 * localBounds.top() + localBounds.height());
            transform = transform.scale3d(1.0, -1.0, 1.0);
            TextureQuadData data(texture, GL_TEXTURE_2D, GL_LINEAR, LayerQuad, &transform, &localBounds, 1.0f, true);
            TilesManager::instance()->shader()->drawQuad(&data);
            m_proxy->releaseFrontBuffer();
            askScreenUpdate |= requestUpdate;
        }
    }
    else
    {
        LOGWEBGL("m_proxy.get() returned NULL");
    }

    return askScreenUpdate;
}
示例#7
0
GLint GraphicsContext3DInternal::checkGLError(const char* s)
{
    GLint error = glGetError();
    if (error == GL_NO_ERROR) {
        LOGWEBGL("%s() OK", s);
    }
    else {
        LOGWEBGL("after %s() glError (0x%x)", s, error);
    }

    return error;
}
示例#8
0
void GraphicsContext3DInternal::startSyncThread()
{
    LOGWEBGL("+startSyncThread()");
    MutexLocker lock(m_threadMutex);
    m_threadState = THREAD_STATE_STOPPED;
    m_syncThread = createThread(syncThreadStart, this, "GraphicsContext3DInternal");
    // Wait for thread to start
    while (m_threadState != THREAD_STATE_RUN) {
        m_threadCondition.wait(m_threadMutex);
    }
    LOGWEBGL("-startSyncThread()");
}
示例#9
0
bool GraphicsContext3DInternal::initEGL()
{
    m_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (m_dpy == EGL_NO_DISPLAY)
        return false;

    EGLint     majorVersion;
    EGLint     minorVersion;
    EGLBoolean returnValue = eglInitialize(m_dpy, &majorVersion, &minorVersion);
    if (returnValue != EGL_TRUE)
        return false;

    LOGWEBGL("EGL version %d.%d", majorVersion, minorVersion);
    const char *s = eglQueryString(m_dpy, EGL_VENDOR);
    LOGWEBGL("EGL_VENDOR = %s", s);
    s = eglQueryString(m_dpy, EGL_VERSION);
    LOGWEBGL("EGL_VERSION = %s", s);
    s = eglQueryString(m_dpy, EGL_EXTENSIONS);
    LOGWEBGL("EGL_EXTENSIONS = %s", s);
    s = eglQueryString(m_dpy, EGL_CLIENT_APIS);
    LOGWEBGL("EGL_CLIENT_APIS = %s", s);

    EGLint config_attribs[21];
    int p = 0;
    config_attribs[p++] = EGL_BLUE_SIZE;
    config_attribs[p++] = 8;
    config_attribs[p++] = EGL_GREEN_SIZE;
    config_attribs[p++] = 8;
    config_attribs[p++] = EGL_RED_SIZE;
    config_attribs[p++] = 8;
    config_attribs[p++] = EGL_SURFACE_TYPE;
    config_attribs[p++] = EGL_PBUFFER_BIT;
    config_attribs[p++] = EGL_RENDERABLE_TYPE;
    config_attribs[p++] = EGL_OPENGL_ES2_BIT;
    config_attribs[p++] = EGL_ALPHA_SIZE;
    config_attribs[p++] = m_attrs.alpha ? 8 : 0;
    if (m_attrs.depth) {
        config_attribs[p++] = EGL_DEPTH_SIZE;
        config_attribs[p++] = 16;
    }
    if (m_attrs.stencil) {
        config_attribs[p++] = EGL_STENCIL_SIZE;
        config_attribs[p++] = 8;
    }
    // Antialiasing currently is not supported.
    m_attrs.antialias = false;
    config_attribs[p] = EGL_NONE;

    EGLint num_configs = 0;
    return (eglChooseConfig(m_dpy, config_attribs, &m_config, 1, &num_configs) == EGL_TRUE);
}
示例#10
0
bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
{
    LOGWEBGL("paintCompositedResultsToCanvas()");
    ImageBuffer* imageBuffer = context->canvas()->buffer();
    const SkBitmap& canvasBitmap =
        imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false);
    SkCanvas canvas(canvasBitmap);

    MutexLocker lock(m_fboMutex);

    FBO* fbo = m_frontFBO;
    if (!fbo)
        return false;

    SkBitmap bitmap;
    bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height, fbo->bytesPerRow());

    unsigned char* bits = NULL;
    if (fbo->lockGraphicBuffer((void**)&bits)) {
        bitmap.setPixels(bits);

        SkRect  dstRect;
        dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height());
        canvas.save();
        canvas.translate(0, SkIntToScalar(imageBuffer->size().height()));
        canvas.scale(SK_Scalar1, -SK_Scalar1);
        canvas.drawBitmapRect(bitmap, 0, dstRect);
        canvas.restore();
        bitmap.setPixels(0);
        fbo->unlockGraphicBuffer();
    }

    return true;
}
示例#11
0
void GraphicsContext3DInternal::reshape(int width, int height)
{
    LOGWEBGL("reshape(%d, %d)", width, height);
    bool mustRestoreFBO = (m_boundFBO != (m_currentFBO ? m_currentFBO->fbo() : 0));

    m_width = width > m_maxwidth ? m_maxwidth : width;
    m_height = height > m_maxheight ? m_maxheight : height;

    stopSyncThread();
    makeContextCurrent();
    m_proxy->setGraphicsContext(0);
    {
        MutexLocker lock(m_fboMutex);
        deleteContext(false);

        if (createContext(false)) {
            if (!mustRestoreFBO) {
                m_boundFBO = m_currentFBO->fbo();
            }
            glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
        }
    }
    m_proxy->setGraphicsContext(this);
    startSyncThread();
}
示例#12
0
void GraphicsContext3DInternal::deleteContext(bool deleteEGLContext)
{
    LOGWEBGL("deleteContext(%s)", deleteEGLContext ? "true" : "false");

    makeContextCurrent();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    m_freeBuffers.clear();
    m_queuedBuffers.clear();
    m_preparedBuffers.clear();
    //[CAPPFIX_WEB_WEBGL] - Handle FBO creation failure
    for (int i = 0; i < m_nfbo; i++) {
        if (m_fbo[i]) {
            delete m_fbo[i];
            m_fbo[i] = 0;
        }
    }
    m_nfbo=0;
    //[CAPPFIX_WEB_WEBGL_END]
    m_currentFBO = 0;
    m_frontFBO = 0;

    eglMakeCurrent(m_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (deleteEGLContext) {
        if (m_surface != EGL_NO_SURFACE) {
            eglDestroySurface(m_dpy, m_surface);
            m_surface = EGL_NO_SURFACE;
        }
        if (m_context != EGL_NO_CONTEXT) {
            eglDestroyContext(m_dpy, m_context);
            m_context = EGL_NO_CONTEXT;
        }
    }
}
示例#13
0
GLuint FBO::createTexture(EGLImageKHR image, int width, int height)
{
    LOGWEBGL("createTexture(image = %p)", image);
    GLuint texture;

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    bool error = false;
    if (image) {
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
        error = (GraphicsContext3DInternal::checkGLError("glEGLImageTargetTexture2DOES")
                 != GL_NO_ERROR);
    }
    else {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        error = (GraphicsContext3DInternal::checkGLError("glTexImage2D()") != GL_NO_ERROR);
    }
    glBindTexture(GL_TEXTURE_2D, 0);
    if (error) {
        glDeleteTextures(1, &texture);
        texture = 0;
    }

    return texture;
}
示例#14
0
void GraphicsContext3DInternal::stopSyncThread()
{
    LOGWEBGL("+stopSyncThread()");
    MutexLocker lock(m_threadMutex);
    if (m_syncThread) {
        m_threadState = THREAD_STATE_STOP;
        // Signal thread to wake up
        m_threadCondition.broadcast();
        // Wait for thread to stop
        while (m_threadState != THREAD_STATE_STOPPED) {
            m_threadCondition.wait(m_threadMutex);
        }
        m_syncThread = 0;
    }
    LOGWEBGL("-stopSyncThread()");
}
示例#15
0
bool GraphicsContext3DInternal::createContext(bool createEGLContext)
{
    LOGWEBGL("createContext()");

    if (createEGLContext) {
        const EGLint context_attribs[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE };
        const EGLint surface_attribs[] = {
            EGL_WIDTH, 1,
            EGL_HEIGHT, 1,
            EGL_NONE };
        m_surface = eglCreatePbufferSurface(m_dpy, m_config, surface_attribs);
        EGLContext context = EGL_NO_CONTEXT;
#if USE(SHARED_TEXTURE_WEBGL)
        context = TilesManager::instance()->getEglContext();
#endif
        m_context = eglCreateContext(m_dpy, m_config, context, context_attribs);
    }
    if (m_context == EGL_NO_CONTEXT) {
        deleteContext(createEGLContext);
        return false;
    }

    makeContextCurrent();
    for (int i = 0; i < NUM_BUFFERS; i++) {
        FBO* tmp = FBO::createFBO(m_dpy, m_width > 0 ? m_width : 1, m_height > 0 ? m_height : 1, m_attrs);
        if (tmp == 0) {
            LOGWEBGL("Failed to create FBO");
            deleteContext(createEGLContext);
            return false;
        }
        m_fbo[i] = tmp;
        //[CAPPFIX_WEB_WEBGL] - Handle FBO creation failure
        m_nfbo++;
        //[CAPPFIX_WEB_WEBGL_END]
        m_freeBuffers.append(tmp);
    }

    m_currentFBO = dequeueBuffer();
    m_boundFBO = m_currentFBO->fbo();
    m_frontFBO = 0;
    glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);

    return true;
}
示例#16
0
//[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin
long GraphicsContext3DInternal::logTickCount(const CString string, const long time, const long min)
{
    const long dtime = getTickCount() - time;
    if (dtime > min/*(msec)*/) {
        LOGWEBGL("[%s] %d ms", string.data(), dtime);
    }
    return dtime;
}
示例#17
0
void GraphicsContext3DInternal::shaderSource(Platform3DObject shader, const String& string)
{
    LOGWEBGL("shaderSource()");
    ShaderSourceEntry entry;

    entry.source = string;

    m_shaderSourceMap.set(shader, entry);
}
示例#18
0
void GraphicsContext3DInternal::recreateSurface()
{
    LOGWEBGL("recreateSurface()");
    if (m_currentFBO != 0)
        // We already have a current surface
        return;
    reshape(m_width, m_height);
    glViewport(m_savedViewport.x, m_savedViewport.y, m_savedViewport.width, m_savedViewport.height);
}
示例#19
0
void GraphicsContext3DInternal::viewport(long x, long y, unsigned long width, unsigned long height)
{
    LOGWEBGL("glViewport(%d, %d, %d, %d)", x, y, width, height);
    glViewport(x, y, width, height);
    m_savedViewport.x = x;
    m_savedViewport.y = y;
    m_savedViewport.width = width;
    m_savedViewport.height = height;
}
示例#20
0
WebGLLayer::WebGLLayer(const WebGLLayer& layer)
    : LayerAndroid(layer)
    , m_proxy(layer.m_proxy)
{
    LOGWEBGL("WebGLLayer::WebGLLayer(const WebGLLayer& %p), this = %p", &layer, this);
    for (int i = 0; i < 2; i++) {
        m_eglImages[i] = layer.m_eglImages[i];
        m_textures[i] = layer.m_textures[i];
    }
}
示例#21
0
WebGLLayer::WebGLLayer(GraphicsContext3DProxy* proxy)
    : LayerAndroid((RenderLayer*)0)
    , m_proxy(proxy)
{
    LOGWEBGL("WebGLLayer::WebGLLayer(GraphicsContext3DProxy* %p), this = %p", proxy, this);
    for (int i = 0; i < 2; i++) {
        m_eglImages[i] = 0;
        m_textures[i] = 0;
    }
}
示例#22
0
String GraphicsContext3DInternal::getShaderSource(Platform3DObject shader)
{
    LOGWEBGL("getShaderSource()");
    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);

    if (result == m_shaderSourceMap.end())
        return "";

    return result->second.source;
}
示例#23
0
void GraphicsContext3DInternal::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
{
    LOGWEBGL("glBindFrameBuffer(%d, %d)", target, buffer);
    makeContextCurrent();
    MutexLocker lock(m_fboMutex);
    if (!buffer && m_currentFBO) {
        buffer = m_currentFBO->fbo();
    }
    glBindFramebuffer(target, buffer);
    m_boundFBO = buffer;
}
示例#24
0
/*
 * Must hold m_fboMutex when calling this function.
 */
FBO* GraphicsContext3DInternal::dequeueBuffer()
{
    LOGWEBGL("GraphicsContext3DInternal::dequeueBuffer()");
    while (m_freeBuffers.isEmpty()) {
        m_fboCondition.wait(m_fboMutex);
    }
    FBO* fbo = m_freeBuffers.takeFirst();
    destroyEGLSync(fbo);

    return fbo;
}
示例#25
0
FBO* FBO::createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attributes)
{
    LOGWEBGL("createFBO()");
    FBO* fbo = new FBO(dpy);

    if (!fbo->init(width, height, attributes)) {
        delete fbo;
        return 0;
    }
    return fbo;
}
示例#26
0
unsigned long GraphicsContext3DInternal::getError()
{
    if (m_syntheticErrors.size() > 0) {
        ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
        unsigned long err = *iter;
        m_syntheticErrors.remove(iter);
        return err;
    }
    LOGWEBGL("glGetError()");
    makeContextCurrent();
    return glGetError();
}
示例#27
0
void GraphicsContext3DInternal::compileShader(Platform3DObject shader)
{
    LOGWEBGL("compileShader()");
    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
    if (result == m_shaderSourceMap.end()) {
        LOGWEBGL("  shader not found");
        return;
    }
    ShaderSourceEntry& entry = result->second;

    int shaderType;
    glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);

    ANGLEShaderType ast = shaderType == GL_VERTEX_SHADER ?
        SHADER_TYPE_VERTEX : SHADER_TYPE_FRAGMENT;

    String src;
    String log;
    bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), ast, src, log);

    entry.log = log;
    entry.isValid = isValid;

    if (!isValid) {
        LOGWEBGL("  shader validation failed");
        return;
    }
    int len = entry.source.length();
    CString cstr = entry.source.utf8();
    const char* s = cstr.data();

    LOGWEBGL("glShaderSource(%s)", cstr.data());
    glShaderSource(shader, 1, &s, &len);

    LOGWEBGL("glCompileShader()");
    glCompileShader(shader);
}
示例#28
0
void GraphicsContext3DInternal::releaseFrontBuffer()
{
    LOGWEBGL("GraphicsContext3DInternal::releaseFrontBuffer()");
    MutexLocker lock(m_fboMutex);
    FBO* fbo = m_frontFBO;

    if (fbo) {
        fbo->setLocked(false);
        if (fbo->sync() != EGL_NO_SYNC_KHR) {
            eglDestroySyncKHR(m_dpy, fbo->sync());
        }
        fbo->setSync();
    }
    updateFrontBuffer();
}
示例#29
0
void GraphicsContext3DInternal::releaseSurface()
{
    LOGWEBGL("releaseSurface(%d)", m_contextId);
    if (m_currentFBO == 0)
        // We don't have any current surface
        return;
    stopSyncThread();
    m_proxy->setGraphicsContext(0);
    {
        MutexLocker lock(m_fboMutex);
        deleteContext(false);
    }
    makeContextCurrent();
    m_proxy->setGraphicsContext(this);
}
示例#30
0
FBO::~FBO()
{
    LOGWEBGL("FBO::~FBO()");
    if (m_image) {
        eglDestroyImageKHR(m_dpy, m_image);
        GraphicsContext3DInternal::checkEGLError("eglDestroyImageKHR");
    }
    if (m_texture)
        glDeleteTextures(1, &m_texture);
    if (m_depthBuffer)
        glDeleteRenderbuffers(1, &m_depthBuffer);
    if (m_stencilBuffer)
        glDeleteRenderbuffers(1, &m_stencilBuffer);
    if (m_fbo)
        glDeleteFramebuffers(1, &m_fbo);
}