Example #1
0
static void
get_texture_2d_image(image_info *info)
{
    GLuint fbo = 0;
    GLint prev_fbo = 0;
    GLint texture;
    GLenum status;

    _glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
    if (!texture)
        return;

    _glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fbo);
    _glGenFramebuffers(1, &fbo);
    _glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                            texture, 0);
    status = _glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE)
        os::log("%s: error: %d\n", __func__, status);
    _glReadPixels(0, 0, info->width, info->height, info->format, info->type, info->pixels);
    /* Don't leak errors to the traced application. */
    (void)_glGetError();

    _glBindFramebuffer(GL_FRAMEBUFFER, prev_fbo);
    _glDeleteFramebuffers(1, &fbo);
}
Example #2
0
void setContext(uintptr_t context_id)
{
    ThreadState *ts = get_ts();
    context_ptr_t ctx;

    context_map_mutex.lock();

    assert(context_map.find(context_id) != context_map.end());
    ctx = context_map[context_id];

    context_map_mutex.unlock();

    ts->current_context = ctx;

    if (!ctx->bound) {
        ctx->profile = glfeatures::getCurrentContextProfile();
        ctx->extensions.getCurrentContextExtensions(ctx->profile);
        ctx->features.load(ctx->profile, ctx->extensions);
        ctx->bound = true;
    }

    if (!ctx->boundDrawable) {
        /*
         * The default viewport and scissor state is set when a context is
         * first made current, with values matching the bound drawable.  Many
         * applications never thouch the default state ever again.
         *
         * Since we currently don't trace window sizes, and rely on viewport
         * calls to deduct, emit fake calls here so that viewport/scissor state
         * can be deducated.
         *
         * FIXME: don't call the real functions here -- just emit the fake
         * calls.
         */
        GLint viewport[4] = {0, 0, 0, 0};
        GLint scissor[4] = {0, 0, 0, 0};
        _glGetIntegerv(GL_VIEWPORT, viewport);
        _glGetIntegerv(GL_SCISSOR_BOX, scissor);

        /*
         * On MacOSX the current context and surface are set independently, and
         * we might be called before both are set, so ignore empty boxes.
         */
        if (viewport[2] && viewport[3] && scissor[2] && scissor[3]) {
            glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
            glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
            ctx->boundDrawable = true;
        }
    }
}
Example #3
0
struct image_info *
_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image)
{
    GLuint tex;
    GLuint bound_tex;
    struct image_info *info;

    info = new image_info;

    memset(info, 0, sizeof *info);

    info->internalformat = GL_RGBA;
    info->format = GL_RGBA;
    info->type = GL_UNSIGNED_BYTE;

    _eglCreateImageKHR_get_image_size(image, info);

    _glGenTextures(1, &tex);
    _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&bound_tex);
    _glBindTexture(GL_TEXTURE_2D, tex);
    _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

    info->size = _glTexImage2D_size(info->format, info->type, info->width, info->height);
    info->pixels = malloc(info->size);

    get_texture_2d_image(info);
    _glBindTexture(GL_TEXTURE_2D, bound_tex);
    _glDeleteBuffers(1, &tex);

    return info;
}
Example #4
0
void
_glGetIntegerv_override(GLenum pname, GLint *params)
{
    _glGetIntegerv(pname, params);

    if (params) {
        const Context *ctx;
        switch (pname) {
        case GL_NUM_EXTENSIONS:
            ctx = getContext();
            if (ctx->profile.major >= 3) {
                const ExtensionsDesc *desc = getExtraExtensions(ctx);
                *params += desc->numStrings;
            }
            break;
        case GL_MAX_LABEL_LENGTH:
            /* We provide our default implementation of KHR_debug when the
             * driver does not.  So return something sensible here.
             */
            if (params[0] == 0) {
                params[0] = 256;
            }
            break;
        default:
            break;
        }
    }
}
Example #5
0
static void
_eglCreateImageKHR_get_image_size(EGLImageKHR image, image_info *info)
{
    GLuint fbo = 0;
    GLuint orig_fbo = 0;
    GLuint texture = 0;
    GLuint orig_texture;
    GLenum status;

    _glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&orig_fbo);
    _glGenFramebuffers(1, &fbo);
    _glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&orig_texture);
    _glGenTextures(1, &texture);
    _glBindTexture(GL_TEXTURE_2D, texture);

    _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

    info->width = 0;
    info->height = 0;

    _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                            GL_TEXTURE_2D, texture, 0);
    status = _glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status == GL_FRAMEBUFFER_COMPLETE) {
        if (detect_size(&info->width, &info->height) != 0)
            os::log("%s: can't detect image size\n", __func__);
    } else {
        os::log("%s: error: %x\n", __func__, status);
    }

    /* Don't leak errors to the traced application. */
    (void)_glGetError();

    _glBindTexture(GL_TEXTURE_2D, orig_texture);
    _glDeleteTextures(1, &texture);

    _glBindFramebuffer(GL_FRAMEBUFFER, orig_fbo);
    _glDeleteFramebuffers(1, &fbo);
}
Example #6
0
static inline size_t
_gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLboolean has_unpack_subimage) {

    unsigned bits_per_element;
    unsigned bits_per_pixel;
    _gl_format_size(format, type, bits_per_element, bits_per_pixel);

    GLint alignment = 4;
    GLint row_length = 0;
    GLint image_height = 0;
    GLint skip_rows = 0;
    GLint skip_pixels = 0;
    GLint skip_images = 0;

    _glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
    if (has_unpack_subimage) {
        _glGetIntegerv(GL_UNPACK_ROW_LENGTH,   &row_length);
        _glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height);
        _glGetIntegerv(GL_UNPACK_SKIP_ROWS,    &skip_rows);
        _glGetIntegerv(GL_UNPACK_SKIP_PIXELS,  &skip_pixels);
        _glGetIntegerv(GL_UNPACK_SKIP_IMAGES,  &skip_images);
    }

    if (row_length <= 0) {
        row_length = width;
    }

    size_t row_stride = (row_length*bits_per_pixel + 7)/8;

    if ((bits_per_element == 1*8 ||
         bits_per_element == 2*8 ||
         bits_per_element == 4*8 ||
         bits_per_element == 8*8) &&
        (GLint)bits_per_element < alignment*8) {
        row_stride = _align(row_stride, alignment);
    }

    if (image_height <= 0) {
        image_height = height;
    }

    /* XXX: GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably
     * not be considered for pixel rectangles. */

    size_t image_stride = image_height*row_stride;

    size_t size = depth*image_stride;

    size += (skip_pixels*bits_per_pixel + 7)/8;
    size += skip_rows*row_stride;
    size += skip_images*image_stride;

    return size;
}
Example #7
0
void
_glGetIntegerv_override(GLenum pname, GLint *params)
{
    _glGetIntegerv(pname, params);

    if (params) {
        switch (pname) {
        case GL_NUM_EXTENSIONS:
            {
                const ExtensionsDesc *desc = getExtraExtensions();
                *params += desc->numStrings;
            }
            break;
        default:
            break;
        }
    }
}
Example #8
0
const GLubyte *
_glGetStringi_override(GLenum name, GLuint index)
{
    switch (name) {
    case GL_EXTENSIONS:
        {
            const ExtensionsDesc *desc = getExtraExtensions();
            GLint numExtensions = 0;
            _glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
            if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
                return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
            }
        }
        break;
    default:
        break;
    }

    return _glGetStringi(name, index);
}
Example #9
0
static int
detect_size(int *width_ret, int *height_ret)
{
    GLint max_tex_size;
    int width;
    int height;

    max_tex_size = 0;
    _glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);

    width = bisect_val(1, max_tex_size, is_valid_width);
    if (width < 0)
        return -1;

    height = bisect_val(1, max_tex_size, is_valid_height);
    if (height < 0)
        return -1;

    *width_ret = width;
    *height_ret = height;

    return 0;
}
Example #10
0
/**
 * Same as glGetIntegerv, but passing the result in the return value.
 */
static inline GLint
_glGetInteger(GLenum pname) {
    GLint param = 0;
    _glGetIntegerv(pname, &param);
    return param;
}
Example #11
0
static inline size_t
_gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLboolean has_unpack_subimage) {
    unsigned num_channels = _gl_format_channels(format);

    unsigned bits_per_element;
    unsigned bits_per_pixel;
    switch (type) {
    case GL_BITMAP:
        bits_per_pixel = bits_per_element = 1;
        break;
    case GL_BYTE:
    case GL_UNSIGNED_BYTE:
        bits_per_element = 8;
        bits_per_pixel = bits_per_element * num_channels;
        break;
    case GL_SHORT:
    case GL_UNSIGNED_SHORT:
    case GL_HALF_FLOAT:
        bits_per_element = 16;
        bits_per_pixel = bits_per_element * num_channels;
        break;
    case GL_INT:
    case GL_UNSIGNED_INT:
    case GL_FLOAT:
        bits_per_element = 32;
        bits_per_pixel = bits_per_element * num_channels;
        break;
    case GL_UNSIGNED_BYTE_3_3_2:
    case GL_UNSIGNED_BYTE_2_3_3_REV:
        bits_per_pixel = bits_per_element = 8;
        break;
    case GL_UNSIGNED_SHORT_4_4_4_4:
    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
    case GL_UNSIGNED_SHORT_5_5_5_1:
    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
    case GL_UNSIGNED_SHORT_5_6_5:
    case GL_UNSIGNED_SHORT_5_6_5_REV:
    case GL_UNSIGNED_SHORT_8_8_MESA:
    case GL_UNSIGNED_SHORT_8_8_REV_MESA:
        bits_per_pixel = bits_per_element = 16;
        break;
    case GL_UNSIGNED_INT_8_8_8_8:
    case GL_UNSIGNED_INT_8_8_8_8_REV:
    case GL_UNSIGNED_INT_10_10_10_2:
    case GL_UNSIGNED_INT_2_10_10_10_REV:
    case GL_UNSIGNED_INT_24_8:
    case GL_UNSIGNED_INT_10F_11F_11F_REV:
    case GL_UNSIGNED_INT_5_9_9_9_REV:
    case GL_UNSIGNED_INT_S8_S8_8_8_NV:
    case GL_UNSIGNED_INT_8_8_S8_S8_REV_NV:
        bits_per_pixel = bits_per_element = 32;
        break;
    case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
        bits_per_pixel = bits_per_element = 64;
        break;
    default:
        os::log("apitrace: warning: %s: unexpected type GLenum 0x%04X\n", __FUNCTION__, type);
        bits_per_pixel = bits_per_element = 0;
        break;
    }

    GLint alignment = 4;
    GLint row_length = 0;
    GLint image_height = 0;
    GLint skip_rows = 0;
    GLint skip_pixels = 0;
    GLint skip_images = 0;

    _glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
    if (has_unpack_subimage) {
        _glGetIntegerv(GL_UNPACK_ROW_LENGTH,   &row_length);
        _glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height);
        _glGetIntegerv(GL_UNPACK_SKIP_ROWS,    &skip_rows);
        _glGetIntegerv(GL_UNPACK_SKIP_PIXELS,  &skip_pixels);
        _glGetIntegerv(GL_UNPACK_SKIP_IMAGES,  &skip_images);
    }

    if (row_length <= 0) {
        row_length = width;
    }

    size_t row_stride = (row_length*bits_per_pixel + 7)/8;

    if ((bits_per_element == 1*8 ||
         bits_per_element == 2*8 ||
         bits_per_element == 4*8 ||
         bits_per_element == 8*8) &&
        (GLint)bits_per_element < alignment*8) {
        row_stride = _align(row_stride, alignment);
    }

    if (image_height <= 0) {
        image_height = height;
    }

    /* XXX: GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably
     * not be considered for pixel rectangles. */

    size_t image_stride = image_height*row_stride;

    size_t size = depth*image_stride;

    size += (skip_pixels*bits_per_pixel + 7)/8;
    size += skip_rows*row_stride;
    size += skip_images*image_stride;

    return size;
}
Example #12
0
static inline GLuint
_glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
{
    GLvoid *temp = 0;
    GLint element_array_buffer = 0;

    if (!count) {
        return 0;
    }

    _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &element_array_buffer);
    if (element_array_buffer) {
        // Read indices from index buffer object
        GLintptr offset = (GLintptr)indices;
        GLsizeiptr size = count*_gl_type_size(type);
        GLvoid *temp = malloc(size);
        if (!temp) {
            return 0;
        }
        memset(temp, 0, size);
        _glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp);
        indices = temp;
    } else {
        if (!indices) {
            return 0;
        }
    }

    GLuint maxindex = 0;
    GLsizei i;
    if (type == GL_UNSIGNED_BYTE) {
        const GLubyte *p = (const GLubyte *)indices;
        for (i = 0; i < count; ++i) {
            if (p[i] > maxindex) {
                maxindex = p[i];
            }
        }
    } else if (type == GL_UNSIGNED_SHORT) {
        const GLushort *p = (const GLushort *)indices;
        for (i = 0; i < count; ++i) {
            if (p[i] > maxindex) {
                maxindex = p[i];
            }
        }
    } else if (type == GL_UNSIGNED_INT) {
        const GLuint *p = (const GLuint *)indices;
        for (i = 0; i < count; ++i) {
            if (p[i] > maxindex) {
                maxindex = p[i];
            }
        }
    } else {
        os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, type);
    }

    if (element_array_buffer) {
        free(temp);
    }

    maxindex += basevertex;

    return maxindex + 1;
}
Example #13
0
static inline size_t
_gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLboolean has_unpack_subimage)
{
    unsigned bits_per_pixel = _gl_format_size(format, type);

    GLint alignment = 4;
    GLint row_length = 0;
    GLint image_height = 0;
    GLint skip_rows = 0;
    GLint skip_pixels = 0;
    GLint skip_images = 0;

    _glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
    if (has_unpack_subimage) {
        _glGetIntegerv(GL_UNPACK_ROW_LENGTH,   &row_length);
        _glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height);
        _glGetIntegerv(GL_UNPACK_SKIP_ROWS,    &skip_rows);
        _glGetIntegerv(GL_UNPACK_SKIP_PIXELS,  &skip_pixels);
        _glGetIntegerv(GL_UNPACK_SKIP_IMAGES,  &skip_images);
    }

    if (row_length <= 0) {
        row_length = width;
    }

    size_t row_stride = (row_length*bits_per_pixel + 7)/8;

    /*
     * The OpenGL specification states that the unpack alignment should be
     * ignored if the number of bits per element is not 1, 2, 4, or 8 times the
     * number of bits in a GL ubyte, but the matter of fact is that the number
     * of bits per element is always one of those.
     */
    if (_is_pot(alignment)) {
        row_stride = _align(row_stride, alignment);
    }

    if (image_height <= 0) {
        image_height = height;
    }

    size_t image_stride = image_height*row_stride;

    /*
     * We can't just do
     *
     *   size = depth*image_stride
     *
     * here as that could result in reading beyond the end of the buffer when
     * selecting sub-rectangles via GL_UNPACK_SKIP_*.
     */
    size_t size = (width*bits_per_pixel + 7)/8;
    if (height > 1) {
        size += (height - 1)*row_stride;
    }
    if (depth > 1) {
        size += (depth - 1)*image_stride;
    }

    /* XXX: GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably
     * not be considered for pixel rectangles. */

    size += (skip_pixels*bits_per_pixel + 7)/8;
    size += skip_rows*row_stride;
    size += skip_images*image_stride;

    return size;
}