<commit_before>
/*
 * Copyright 2013 The Servo Project Developers
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gl/SkNativeSharedGLContext.h"
#include "gl/GrGLUtil.h"

SkNativeSharedGLContext::SkNativeSharedGLContext(GrGLNativeContext& nativeContext)
    : fContext(NULL)
    , fDisplay(nativeContext.fDisplay)
    , fVisualInfo(nativeContext.fVisualInfo)
    , fGrContext(NULL)
    , fGL(NULL)
    , fFBO(0)
    , fTextureID(0)
    , fDepthStencilBufferID(0)
    , fPixmap(0)
    , fGlxPixmap(0) {
}

SkNativeSharedGLContext::~SkNativeSharedGLContext() {
    if (fGlxPixmap) {
        destroyGLResources();
    }
    if (fPixmap) {
        XFreePixmap(fDisplay, fPixmap);
    }
    if (fGrContext) {
        fGrContext->Release();
    }
    SkSafeUnref(fGL);
    this->destroyGLContext();
}

void SkNativeSharedGLContext::destroyGLResources() {
    if (fGL) {
        // We need this thread to grab the GLX context before we can make
        // OpenGL calls.  But glXMakeCurrent() will flush the old context,
        // which might have been uninitialized.  Calling with (None, NULL)
        // first solves this problem (somehow).
        glXMakeCurrent(fDisplay, None, NULL);
        glXMakeCurrent(fDisplay, fGlxPixmap, fContext);

        SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO));
        SK_GL_NOERRCHECK(*this, DeleteTextures(1, &fTextureID));
        SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
    }

    glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
    fGlxPixmap = 0;
}

void SkNativeSharedGLContext::destroyGLContext() {
    glXMakeCurrent(fDisplay, None, NULL);
    if (NULL != fContext) {
        glXDestroyContext(fDisplay, fContext);
    }
}

const GrGLInterface* SkNativeSharedGLContext::createGLContext(const int width, const int height) {
    SkASSERT(NULL == fContext);

    // Create the base pixmap and GLX pixmap.
    //
    // TODO(pcwalton): This is inefficient. It would be better to have the caller pass in the
    // pixmap.
    int screen = DefaultScreen(fDisplay);
    Drawable root = RootWindow(fDisplay, screen);
    fPixmap = XCreatePixmap(fDisplay, root, width, height, fVisualInfo->depth);
    fGlxPixmap = glXCreateGLXPixmap(fDisplay, fVisualInfo, fPixmap);

    fContext = glXCreateContext(fDisplay, fVisualInfo, NULL, true);
    if (NULL == fContext) {
        SkDebugf("glXCreateContext failed with %d.", fContext);<commit_msg>Unbind pixmap from context when it is destroyed - fixes crash under xfvb.<commit_after>
/*
 * Copyright 2013 The Servo Project Developers
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gl/SkNativeSharedGLContext.h"
#include "gl/GrGLUtil.h"

SkNativeSharedGLContext::SkNativeSharedGLContext(GrGLNativeContext& nativeContext)
    : fContext(NULL)
    , fDisplay(nativeContext.fDisplay)
    , fVisualInfo(nativeContext.fVisualInfo)
    , fGrContext(NULL)
    , fGL(NULL)
    , fFBO(0)
    , fTextureID(0)
    , fDepthStencilBufferID(0)
    , fPixmap(0)
    , fGlxPixmap(0) {
}

SkNativeSharedGLContext::~SkNativeSharedGLContext() {
    if (fGlxPixmap) {
        destroyGLResources();
    }
    if (fPixmap) {
        XFreePixmap(fDisplay, fPixmap);
    }
    if (fGrContext) {
        fGrContext->Release();
    }
    SkSafeUnref(fGL);
    this->destroyGLContext();
}

void SkNativeSharedGLContext::destroyGLResources() {
    if (fGL) {
        // We need this thread to grab the GLX context before we can make
        // OpenGL calls.  But glXMakeCurrent() will flush the old context,
        // which might have been uninitialized.  Calling with (None, NULL)
        // first solves this problem (somehow).
        glXMakeCurrent(fDisplay, None, NULL);
        glXMakeCurrent(fDisplay, fGlxPixmap, fContext);

        SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO));
        SK_GL_NOERRCHECK(*this, DeleteTextures(1, &fTextureID));
        SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
    }

    glXMakeCurrent(fDisplay, None, NULL);
    glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
    fGlxPixmap = 0;
}

void SkNativeSharedGLContext::destroyGLContext() {
    glXMakeCurrent(fDisplay, None, NULL);
    if (NULL != fContext) {
        glXDestroyContext(fDisplay, fContext);
    }
}

const GrGLInterface* SkNativeSharedGLContext::createGLContext(const int width, const int height) {
    SkASSERT(NULL == fContext);

    // Create the base pixmap and GLX pixmap.
    //
    // TODO(pcwalton): This is inefficient. It would be better to have the caller pass in the
    // pixmap.
    int screen = DefaultScreen(fDisplay);
    Drawable root = RootWindow(fDisplay, screen);
    fPixmap = XCreatePixmap(fDisplay, root, width, height, fVisualInfo->depth);
    fGlxPixmap = glXCreateGLXPixmap(fDisplay, fVisualInfo, fPixmap);

    fContext = glXCreateContext(fDisplay, fVisualInfo, NULL, true);
    if (NULL == fContext) {
        SkDebugf("glXCreateContext failed with %d.", fContext);
{'fraction_non_alphanumeric': 0.10604265402843602, 'fraction_numerical': 0.005134281200631911, 'mean_word_length': 3.5385304659498207, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6123579', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1632, 'n_words': 387}