Example #1
0
static void retrace_eglChooseConfig(trace::Call &call) {
    if (!call.ret->toSInt()) {
        return;
    }

    trace::Array *attrib_array = call.arg(1).toArray();
    trace::Array *config_array = call.arg(2).toArray();
    trace::Array *num_config_ptr = call.arg(4).toArray();
    if (!attrib_array || !config_array || !num_config_ptr) {
        return;
    }

    glprofile::Profile profile;
    unsigned renderableType = parseAttrib(attrib_array, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
    std::cerr << "renderableType = " << renderableType << "\n";
    if (renderableType & EGL_OPENGL_BIT) {
        profile = glprofile::Profile(glprofile::API_GL, 1, 0);
    } else {
        profile.api = glprofile::API_GLES;
        if (renderableType & EGL_OPENGL_ES3_BIT) {
            profile.major = 3;
        } else if (renderableType & EGL_OPENGL_ES2_BIT) {
            profile.major = 2;
        } else {
            profile.major = 1;
        }
    }

    unsigned num_config = num_config_ptr->values[0]->toUInt();
    for (unsigned i = 0; i < num_config; ++i) {
        unsigned long long orig_config = config_array->values[i]->toUIntPtr();
        profile_map[orig_config] = profile;
    }
}
Example #2
0
static void retrace_memcpy(trace::Call &call) {
    void * destPtr;
    size_t destLen;
    retrace::toRange(call.arg(0), destPtr, destLen);

    void * srcPtr;
    size_t srcLen;
    retrace::toRange(call.arg(1), srcPtr, srcLen);

    size_t n = call.arg(2).toUInt();

    if (!destPtr || !srcPtr || !n) {
        return;
    }

    if (n > destLen) {
        retrace::warning(call) << "dest buffer overflow of " << n - destLen << " bytes\n";
    }

    if (n > srcLen) {
        retrace::warning(call) << "src buffer overflow of " << n - srcLen << " bytes\n";
    }

    n = std::min(n, destLen);
    n = std::min(n, srcLen);

    memcpy(destPtr, srcPtr, n);
}
Example #3
0
static void retrace_wglUseFontBitmapsAW(trace::Call &call)
{
    bool ret = call.ret->toBool();
    if (!ret) {
        return;
    }

    uint32_t first = call.arg(1).toUInt();
    uint32_t count = call.arg(2).toUInt();
    uint32_t listBase = call.arg(3).toUInt();

    GLint row_length = 0;
    GLint alignment = 4;
    _glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
    _glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);

    for (uint32_t i = 0; i < count; ++i) {
        uint32_t dwChar = (first + i) % 256;
        const Bitmap *bm = &wglSystemFontBitmaps[dwChar];

        glPixelStorei(GL_UNPACK_ROW_LENGTH, bm->width);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

        glNewList(listBase + i, GL_COMPILE);

        glBitmap(bm->width, bm->height,
                 bm->xorig, bm->yorig, bm->xmove, bm->ymove,
                 (const GLubyte *)bm->pixels);

        glEndList();
    }

    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
    glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
}
Example #4
0
static void retrace_glXMakeCurrent(Trace::Call &call) {
    glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
    glws::Context *new_context = getContext(call.arg(2).toUIntPtr());

    if (new_drawable == drawable && new_context == context) {
        return;
    }

    if (drawable && context) {
        glFlush();
        if (!double_buffer) {
            frame_complete(call.no);
        }
    }

    bool result = ws->makeCurrent(new_drawable, new_context);

    if (new_drawable && new_context && result) {
        drawable = new_drawable;
        context = new_context;
    } else {
        drawable = NULL;
        context = NULL;
    }
}
Example #5
0
static void retrace_wglCreatePbufferARB(trace::Call &call) {
    unsigned long long orig_pbuffer = call.ret->toUIntPtr();
    if (!orig_pbuffer) {
        return;
    }

    int iWidth = call.arg(2).toUInt();
    int iHeight = call.arg(3).toUInt();
    const trace::Value *attribs = &call.arg(4);
    glws::pbuffer_info pbInfo = {0, 0, false};

    // XXX parse attrib list to populate pbInfo
    int k;

    k = parseAttrib(attribs, WGL_TEXTURE_FORMAT_ARB, WGL_NO_TEXTURE_ARB);
    switch (k) {
    case WGL_TEXTURE_RGB_ARB:
        pbInfo.texFormat = GL_RGB;
        break;
    case WGL_TEXTURE_RGBA_ARB:
        pbInfo.texFormat = GL_RGBA;
        break;
    case WGL_NO_TEXTURE_ARB:
        pbInfo.texFormat = GL_NONE;
        break;
    default:
        std::cerr << "error: invalid value for WGL_TEXTURE_FORMAT_ARB\n";
        pbInfo.texFormat = GL_NONE;
    }

    k = parseAttrib(attribs, WGL_TEXTURE_TARGET_ARB, WGL_NO_TEXTURE_ARB);
    switch (k) {
    case WGL_TEXTURE_CUBE_MAP_ARB:
        pbInfo.texTarget = GL_TEXTURE_CUBE_MAP;
        break;
    case WGL_TEXTURE_1D_ARB:
        pbInfo.texTarget = GL_TEXTURE_1D;
        break;
    case WGL_TEXTURE_2D_ARB:
        pbInfo.texTarget = GL_TEXTURE_2D;
        break;
    case WGL_NO_TEXTURE_ARB:
        pbInfo.texTarget = GL_NONE;
        break;
    default:
        std::cerr << "error: invalid value for WGL_TEXTURE_TARGET_ARB\n";
        pbInfo.texTarget = GL_NONE;
    }

    pbInfo.texMipmap = !!parseAttrib(attribs, WGL_MIPMAP_TEXTURE_ARB, 0);

    // WGL interface needs the HDC
    pbInfo.hdc_drawable = getDrawable(call.arg(0).toUInt());

    glws::Drawable *drawable = glretrace::createPbuffer(iWidth, iHeight,
                                                        &pbInfo);

    pbuffer_map[orig_pbuffer] = drawable;
}
Example #6
0
static void retrace_glXCopySubBufferMESA(trace::Call &call) {
    glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
    int x = call.arg(2).toSInt();
    int y = call.arg(3).toSInt();
    int width = call.arg(4).toSInt();
    int height = call.arg(5).toSInt();

    drawable->copySubBuffer(x, y, width, height);
}
Example #7
0
static void retrace_memcpy(trace::Call &call) {
    void * dest = toPointer(call.arg(0));
    void * src  = toPointer(call.arg(1));
    size_t n    = call.arg(2).toUInt();

    if (!dest || !src || !n) {
        return;
    }

    memcpy(dest, src, n);
}
Example #8
0
static void retrace_glXMakeCurrent(trace::Call &call) {
    if (call.ret && !call.ret->toBool()) {
        // If false was returned then any previously current rendering context
        // and drawable remain unchanged.
        return;
    }

    glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
    Context *new_context = getContext(call.arg(2).toUIntPtr());

    glretrace::makeCurrent(call, new_drawable, new_context);
}
Example #9
0
static void display(void) {
    startTime = OS::GetTime();
    Trace::Call *call;

    while ((call = parser.parse_call())) {
        const char *name = call->name();

        if (retrace::verbosity >= 1) {
            std::cout << *call;
            std::cout.flush();
        }

        if (name[0] == 'C' && name[1] == 'G' && name[2] == 'L') {
            glretrace::retrace_call_cgl(*call);
        }
        else if (name[0] == 'w' && name[1] == 'g' && name[2] == 'l') {
            glretrace::retrace_call_wgl(*call);
        }
        else if (name[0] == 'g' && name[1] == 'l' && name[2] == 'X') {
            glretrace::retrace_call_glx(*call);
        } else {
            retrace::retrace_call(*call);
        }

        if (!insideGlBeginEnd &&
            drawable && context &&
            call->no >= dump_state) {
            glstate::dumpCurrentContext(std::cout);
            exit(0);
        }

        delete call;
    }

    // Reached the end of trace
    glFlush();

    long long endTime = OS::GetTime();
    float timeInterval = (endTime - startTime) * 1.0E-6;

    if (retrace::verbosity >= -1) { 
        std::cout << 
            "Rendered " << frame << " frames"
            " in " <<  timeInterval << " secs,"
            " average of " << (frame/timeInterval) << " fps\n";
    }

    if (wait) {
        while (ws->processEvents()) {}
    } else {
        exit(0);
    }
}
Example #10
0
static void retrace_wglCreatePbufferARB(trace::Call &call) {
    unsigned long long orig_pbuffer = call.ret->toUIntPtr();
    if (!orig_pbuffer) {
        return;
    }

    int iWidth = call.arg(2).toUInt();
    int iHeight = call.arg(3).toUInt();

    glws::Drawable *drawable = glretrace::createPbuffer(iWidth, iHeight);

    pbuffer_map[orig_pbuffer] = drawable;
}
Example #11
0
static void retrace_wglCreateContextAttribsARB(trace::Call &call) {
    unsigned long long orig_context = call.ret->toUIntPtr();
    if (!orig_context) {
        return;
    }

    Context *share_context = getContext(call.arg(1).toUIntPtr());

    const trace::Value * attribList = &call.arg(2);
    glfeatures::Profile profile = parseContextAttribList(attribList);

    Context *context = glretrace::createContext(share_context, profile);
    context_map[orig_context] = context;
}
Example #12
0
static void retrace_wglMakeCurrent(trace::Call &call) {
    bool ret = call.ret->toBool();

    glws::Drawable *new_drawable = NULL;
    Context *new_context = NULL;
    if (ret) {
        unsigned long long hglrc = call.arg(1).toUIntPtr();
        if (hglrc) {
            new_drawable = getDrawable(call.arg(0).toUIntPtr());
            new_context = getContext(hglrc);
        }
    }

    glretrace::makeCurrent(call, new_drawable, new_context);
}
Example #13
0
static void retrace_eglBindAPI(trace::Call &call) {
    if (!call.ret->toBool()) {
        return;
    }

    current_api = call.arg(0).toUInt();
}
Example #14
0
void Retracer::retrace(trace::Call &call) {
    call_dumped = false;

    if (verbosity >= 1) {
        dumpCall(call);
    }

    Callback callback = 0;

    trace::Id id = call.sig->id;
    if (id >= callbacks.size()) {
        callbacks.resize(id + 1);
        callback = 0;
    } else {
        callback = callbacks[id];
    }

    if (!callback) {
        Map::const_iterator it = map.find(call.name());
        if (it == map.end()) {
            callback = &unsupported;
        } else {
            callback = it->second;
        }
        callbacks[id] = callback;
    }

    assert(callback);
    assert(callbacks[id] == callback);

    callback(call);
}
Example #15
0
static void retrace_glXCreateContextAttribsARB(Trace::Call &call) {
    unsigned long long orig_context = call.ret->toUIntPtr();
    glws::Context *share_context = getContext(call.arg(2).toUIntPtr());

    glws::Context *context = ws->createContext(glretrace::visual, share_context);
    context_map[orig_context] = context;
}
Example #16
0
static void retrace_wglShareLists(trace::Call &call) {
    bool ret = call.ret->toBool();
    if (!ret) {
        return;
    }

    unsigned long long hglrc1 = call.arg(0).toUIntPtr();
    unsigned long long hglrc2 = call.arg(1).toUIntPtr();

    Context *share_context = getContext(hglrc1);
    Context *old_context = getContext(hglrc2);

    glfeatures::Profile profile = old_context->profile();
    Context *new_context = glretrace::createContext(share_context, profile);
    if (new_context) {
        glretrace::Context *currentContext = glretrace::getCurrentContext();
        if (currentContext == old_context) {
            glretrace::makeCurrent(call, currentContext->drawable, new_context);
        }

        context_map[hglrc2] = new_context;
        
        old_context->release();
    }
}
Example #17
0
static void retrace_wglSetPbufferAttribARB(trace::Call &call) {
    glws::Drawable *pbuffer = pbuffer_map[call.arg(0).toUIntPtr()];
    const trace::Value * attribList = &call.arg(1);

    // call the window system's setPbufferAttrib function.
    {
        int attribs[100], j = 0;
        const trace::Array *attribs_ = attribList ? attribList->toArray() : NULL;

        for (size_t i = 0; i + 1 < attribs_->values.size(); i += 2) {
            int param_i = attribs_->values[i]->toSInt();
            if (param_i == 0) {
                attribs[j] = 0;
            }

            attribs[j] = param_i;
            attribs[j+1] = attribs_->values[i+1]->toSInt();
        }

        glretrace::setPbufferAttrib(pbuffer, attribs);
    }

    if (!pbuffer || !attribList)
        return;

    // Update the glws::Drawable's fields
    const int undefined = -99999;
    int val;

    val = parseAttrib(attribList, WGL_MIPMAP_LEVEL_ARB, undefined);
    if (val != undefined) {
        pbuffer->mipmapLevel = val;
    }

    val = parseAttrib(attribList, WGL_CUBE_MAP_FACE_ARB, undefined);
    if (val != undefined) {
        // Drawable::cubeFace is integer in [0..5]
        val -= WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
        if (val < 0 || val > 5) {
            fprintf(stderr, "Invalid WGL_CUBE_MAP_FACE_ARB value!\n");
        }
        else {
            pbuffer->cubeFace = val;
        }
    }
}
Example #18
0
static void retrace_CGLSetSurface(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    unsigned long long ctx = call.arg(0).toUIntPtr();
    unsigned long long cid = call.arg(1).toUInt();
    int wid = call.arg(2).toUInt();
    int sid = call.arg(3).toUInt();

    (void)cid;
    (void)wid;

    glws::Drawable *drawable = getDrawable(sid);

    context_drawable_map[ctx] = drawable;
}
Example #19
0
static void retrace_CGLClearDrawable(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    unsigned long long ctx = call.arg(0).toUIntPtr();

    context_drawable_map[ctx] = NULL;
}
Example #20
0
static void retrace_glXDestroyPbuffer(trace::Call &call) {
    glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());

    if (!drawable) {
        return;
    }

    delete drawable;
}
Example #21
0
static void retrace_wglUseFontOutlinesAW(trace::Call &call)
{
    bool ret = call.ret->toBool();
    if (!ret) {
        return;
    }

    uint32_t first = call.arg(1).toUInt();
    uint32_t count = call.arg(2).toUInt();
    uint32_t listBase = call.arg(3).toUInt();
    float extrusion = call.arg(5).toFloat();

    for (uint32_t i = 0; i < count; ++i) {
        glNewList(listBase + i, GL_COMPILE);
        wglSystemFontOutlines(first + i, extrusion);
        glEndList();
    }
}
Example #22
0
static void retrace_CGLSetSurface(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    unsigned long long ctx = call.arg(0).toUIntPtr();
    unsigned long long cid = call.arg(1).toUInt();
    int wid = call.arg(2).toUInt();
    int sid = call.arg(3).toUInt();

    (void)cid;
    (void)wid;

    Context *context = getContext(ctx);
    if (context) {
        glws::Drawable *drawable = getDrawable(sid, context->profile());
        context->drawable = drawable;
    }
}
Example #23
0
static void retrace_CGLCreateContext(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    trace::Value & pix = call.argByName("pix");
    const PixelFormat *pixelFormat = retrace::asObjPointer<PixelFormat>(call, pix);
    glprofile::Profile profile = pixelFormat ? pixelFormat->profile : glretrace::defaultProfile;

    unsigned long long share = call.arg(1).toUIntPtr();
    Context *sharedContext = getContext(share);

    const trace::Array *ctx_ptr = call.arg(2).toArray();
    assert(ctx_ptr);
    unsigned long long ctx = ctx_ptr->values[0]->toUIntPtr();

    Context *context = glretrace::createContext(sharedContext, profile);
    context_map[ctx] = context;
}
Example #24
0
static void retrace_CGLSetVirtualScreen(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    GLint screen = call.arg(1).toSInt();
    if (screen != 0) {
        retrace::warning(call) << "multiple virtual screens unsupported\n";
    }
}
Example #25
0
static void retrace_wglGetPbufferDCARB(trace::Call &call) {
    unsigned long long orig_hdc = call.ret->toUIntPtr();
    if (!orig_hdc) {
        return;
    }

    glws::Drawable *pbuffer = pbuffer_map[call.arg(0).toUIntPtr()];

    drawable_map[orig_hdc] = pbuffer;
}
Example #26
0
static void retrace_glXDestroyContext(trace::Call &call) {
    ContextMap::iterator it;
    it = context_map.find(call.arg(1).toUIntPtr());
    if (it == context_map.end()) {
        return;
    }

    it->second->release();

    context_map.erase(it);
}
Example #27
0
static void retrace_CGLClearDrawable(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    unsigned long long ctx = call.arg(0).toUIntPtr();
    Context *context = getContext(ctx);
    if (context) {
        context->drawable = NULL;
    }
}
Example #28
0
static void retrace_glXCreateContext(trace::Call &call) {
    unsigned long long orig_context = call.ret->toUIntPtr();
    if (!orig_context) {
        return;
    }

    Context *share_context = getContext(call.arg(2).toUIntPtr());

    Context *context = glretrace::createContext(share_context);
    context_map[orig_context] = context;
}
Example #29
0
static void retrace_eglMakeCurrent(trace::Call &call) {
    if (!call.ret->toSInt()) {
        // Previously current rendering context and surfaces (if any) remain
        // unchanged.
        return;
    }

    glws::Drawable *new_drawable = getDrawable(call.arg(1).toUIntPtr());
    Context *new_context = getContext(call.arg(3).toUIntPtr());

    // Try to support GL_OES_surfaceless_context by creating a dummy drawable.
    if (new_context && !new_drawable) {
        if (!null_drawable) {
            null_drawable = glretrace::createDrawable(last_profile);
        }
        new_drawable = null_drawable;
    }

    glretrace::makeCurrent(call, new_drawable, new_context);
}
Example #30
0
static void retrace_CGLDestroyPixelFormat(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    trace::Value & pix = call.argByName("pix");

    PixelFormat *pixelFormat = retrace::asObjPointer<PixelFormat>(call, pix);
    delete pixelFormat;

    retrace::delObj(pix);
}