Example #1
0
 def emitFakeTexture2D(self):
     function = glapi.getFunctionByName('glTexImage2D')
     instances = function.argNames()
     print '        unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
     for arg in function.args:
         assert not arg.output
         self.serializeArg(function, arg)
     print '        trace::localWriter.endEnter();'
     print '        trace::localWriter.beginLeave(_fake_call);'
     print '        trace::localWriter.endLeave();'
Example #2
0
 def emitFakeTexture2D(self):
     function = glapi.getFunctionByName('glTexImage2D')
     instances = function.argNames()
     print '        unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (
         function.name, )
     for arg in function.args:
         assert not arg.output
         self.serializeArg(function, arg)
     print '        trace::localWriter.endEnter();'
     print '        trace::localWriter.beginLeave(_fake_call);'
     print '        trace::localWriter.endLeave();'
Example #3
0
    def traceFunctionImplBody(self, function):
        if function.name.startswith('wgl'):
            # When implementing WGL extensions OpenGL ICDs often have no
            # alternative to calling back into OPENGL32.DLL's wgl* entry points
            # due to lack of extensibility in the ICD interface.  These
            # internal calls are not only visually confusing but can actually
            # cause problems when tracing, and replaying.  A particularly nasty
            # case is wglCreateContextAttribsARB which ends up calling
            # wglCreateContext/wglCreateLayerContext to obtain a HGLRC that's
            # recognizable by OPENGL32.DLL.  Therefore we need to detect and
            # dispatch internal calls, without further ado.
            print(r'    if (_reentrant) {')
            self.invokeFunction(function)
            if function.type is not Void:
                print('    return _result;')
            print(r'    }')
            print(r'    ReentryScope _reentry;')
            print(r'    (void)_reentry;')
            print()

        if function.name in self.destroyContextFunctionNames:
            # Unlike other GL APIs like EGL or GLX, WGL will make the context
            # inactive if it's currently the active context.
            print('    if (_wglGetCurrentContext() == hglrc) {')
            print('        gltrace::clearContext();')
            print('    }')
            print('    gltrace::releaseContext((uintptr_t)hglrc);')

        # Emit a fake string marker describing the current GDI font
        if function.name.startswith('wglUseFont'):
            print(
                r'    HFONT hFont = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT));'
            )
            print(r'    if (hFont != nullptr) {')
            print(r'        LOGFONT lf;')
            print(r'        if (GetObject(hFont, sizeof lf, &lf) != 0) {')
            print(r'            std::ostringstream ss;')
            print(r'            ss << "lfFaceName = " << lf.lfFaceName')
            print(r'               << ", lfHeight = " << lf.lfHeight')
            print(r'               << ", lfWeight = " << lf.lfWeight;')
            print(r'            if (lf.lfItalic) ss << ", lfItalic = 1";')
            print(
                r'            if (lf.lfUnderline) ss << ", lfUnderline = 1";')
            print(
                r'            if (lf.lfStrikeOut) ss << ", lfStrikeOut = 1";')
            print(r'            _fakeStringMarker(ss.str());')
            print(r'        }')
            print(r'    }')
            print()

        # Emit fake glBitmap calls in the trace on wglUseFontBitmapsA.
        # This enables to capture the real bitmaps and replay them outside Windows.
        #
        # XXX: In spite what
        # https://msdn.microsoft.com/en-us/library/windows/desktop/dd374392.aspx
        # implies, GetGlyphOutline(GGO_BITMAP) does not seem to work with
        # certain fonts.  The only solution is to draw the font charactors with
        # a HBITMAP like the old Mesa fxwgl.c code used to do.  That too, seems
        # to be the way that opengl32.dll implements wglUseFontBitmaps.
        #
        if function.name == 'wglUseFontBitmapsA':

            self.invokeFunction(function)

            # Emit a fake string marker with the original call
            print(r'    {')
            print(r'        std::ostringstream ss;')
            print(
                r'        ss << __FUNCTION__ << "(hdc = " << hdc << ", first = " << first << ", count = " << count << ", listBase = " << listBase << ") = " << (_result ? "TRUE" : "FALSE");'
            )
            print(r'        _fakeStringMarker(ss.str());')
            print(r'    }')
            print()

            glNewList = glapi.getFunctionByName('glNewList')
            glBitmap = glapi.getFunctionByName('glBitmap')
            glEndList = glapi.getFunctionByName('glEndList')

            print(r'    if (_result) {')

            print(r'        assert(hFont != nullptr);')
            print()

            print(r'        BOOL bRet;')
            print(r'        TEXTMETRIC tm;')
            print(r'        bRet = GetTextMetricsA(hdc, &tm);')
            print(r'        assert(bRet);')
            print()
            print(r'        HDC memDC = CreateCompatibleDC(hdc);')
            print()
            print(r'        SetMapMode(memDC, MM_TEXT);')
            print(r'        SetTextAlign(memDC, TA_BASELINE);')
            print(r'        SetBkColor(memDC, RGB(0, 0, 0));')
            print(r'        SetBkMode(memDC, OPAQUE);')
            print(r'        SetTextColor(memDC, RGB(255,255,255));')
            print()
            print(
                r'        BITMAPINFO * bmi = (BITMAPINFO *)malloc(offsetof(BITMAPINFO, bmiColors[2]));'
            )
            print(
                r'        ZeroMemory(&bmi->bmiHeader, sizeof bmi->bmiHeader);')
            print(r'        bmi->bmiHeader.biSize = sizeof bmi->bmiHeader;')
            print(r'        bmi->bmiHeader.biPlanes = 1;')
            print(r'        bmi->bmiHeader.biBitCount = 1;')
            print(r'        bmi->bmiHeader.biCompression = BI_RGB;')
            print(r'        bmi->bmiColors[0].rgbBlue     = 0;')
            print(r'        bmi->bmiColors[0].rgbGreen    = 0;')
            print(r'        bmi->bmiColors[0].rgbRed      = 0;')
            print(r'        bmi->bmiColors[0].rgbReserved = 0;')
            print(r'        bmi->bmiColors[1].rgbBlue     = 255;')
            print(r'        bmi->bmiColors[1].rgbGreen    = 255;')
            print(r'        bmi->bmiColors[1].rgbRed      = 255;')
            print(r'        bmi->bmiColors[1].rgbReserved = 0;')
            print()
            print(r'        for (DWORD i = 0; i < count; ++i) {')
            print(r'            _fake_glNewList(listBase + i, GL_COMPILE);')
            print()
            print(r'            char cChar = first + i;')
            print()
            print(r'            // TODO: Use GetCharABSWidths')
            print(
                r'            // http://www.codeproject.com/Articles/14915/Width-of-text-in-italic-font'
            )
            print(
                r'            // https://support.microsoft.com/en-us/kb/94646')
            print(r'            SIZE size;')
            print(
                r'            bRet = GetTextExtentPoint32A(hdc, &cChar, 1, &size);'
            )
            print(r'            if (bRet) {')
            print(r'                assert(size.cx >= 0);')
            print(r'                assert(size.cy >= 0);')
            print()
            print(r'                // Round width to 32 pixels')
            print(r'                int nWidth = (size.cx + 0x1f) & ~0x1f;')
            print(r'                int nHeight = size.cy;')
            print()
            print(r'                DWORD dwBytes = nWidth / 8 * nHeight;')
            print(r'                LPVOID lpvBits = NULL;')
            print(r'                if (dwBytes) {')
            print(r'                    lpvBits = malloc(dwBytes);')
            print()
            print(
                r'                    HBITMAP memBM = CreateCompatibleBitmap(memDC, nWidth, nHeight);'
            )
            print()
            print(
                r'                    HGDIOBJ origBM = SelectObject(memDC, memBM);'
            )
            print()
            print(
                r'                    PatBlt(memDC, 0, 0, nWidth, nHeight, BLACKNESS);'
            )
            print(r'                    SelectObject(memDC, hFont);')
            print()
            print(r'                    bmi->bmiHeader.biWidth  = nWidth;')
            print(r'                    bmi->bmiHeader.biHeight = nHeight;')
            print()
            print(
                r'                    bRet = TextOutA(memDC, 0, tm.tmAscent, &cChar, 1);'
            )
            print(r'                    assert(bRet);')
            print()
            print(r'                    SelectObject(memDC, origBM);')
            print()
            print(
                r'                    int nScanLines = GetDIBits(memDC, memBM, 0, nHeight, lpvBits, bmi, DIB_RGB_COLORS);'
            )
            print(r'                    assert(nScanLines == nHeight);')
            print()
            print(r'                    DeleteObject(memBM);')
            print(r'                }')
            print()
            print(r'                GLsizei width  = nWidth;')
            print(r'                GLfloat height = nHeight;')
            print(r'                GLfloat xorig  = 0;')
            print(r'                GLfloat yorig  = tm.tmDescent;')
            print(r'                GLfloat xmove  = size.cx;')
            print(r'                GLfloat ymove  = 0;')
            print(
                r'                const GLubyte *bitmap = (const GLubyte *)lpvBits;'
            )
            print(r'                if (bitmap == NULL) {')
            print(
                r'                    // We still need to emit an empty glBitmap for empty characters like spaces;'
            )
            print(r'                    width = height = xorig = yorig = 0;')
            print(r'                }')

            # FIXME: glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
            # FIXME: glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
            print()
            print(
                r'                _fake_glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap);'
            )
            print()
            print(r'                free(lpvBits);')
            print(r'            }')
            print(r'            _fake_glEndList();')
            print(r'        }')
            print()
            print(r'        DeleteDC(memDC);')
            print(r'        free(bmi);')

            print(r'    } // _result')
            return

        GlTracer.traceFunctionImplBody(self, function)

        if function.name == 'wglCreateContextAttribsARB':
            print('    if (_result)')
            print(
                '        gltrace::createContext((uintptr_t)_result, (uintptr_t)hShareContext);'
            )
        elif function.name in self.createContextFunctionNames:
            print('    if (_result)')
            print('        gltrace::createContext((uintptr_t)_result, 0);')

        if function.name in self.makeCurrentFunctionNames:
            print('    if (_result) {')
            print('        if (hglrc != NULL)')
            print('            gltrace::setContext((uintptr_t)hglrc);')
            print('        else')
            print('            gltrace::clearContext();')
            print('    }')
Example #4
0
    def traceFunctionImplBody(self, function):
        if function.name.startswith('wgl'):
            # When implementing WGL extensions OpenGL ICDs often have no
            # alternative to calling back into OPENGL32.DLL's wgl* entry points
            # due to lack of extensibility in the ICD interface.  These
            # internal calls are not only visually confusing but can actually
            # cause problems when tracing, and replaying.  A particularly nasty
            # case is wglCreateContextAttribsARB which ends up calling
            # wglCreateContext/wglCreateLayerContext to obtain a HGLRC that's
            # recognizable by OPENGL32.DLL.  Therefore we need to detect and
            # dispatch internal calls, without further ado.
            print r'    if (_reentrant) {'
            self.invokeFunction(function)
            if function.type is not Void:
                print '    return _result;'
            print r'    }'
            print r'    ReentryScope _reentry;'
            print r'    (void)_reentry;'
            print

        if function.name in self.destroyContextFunctionNames:
            # Unlike other GL APIs like EGL or GLX, WGL will make the context
            # inactive if it's currently the active context.
            print '    if (_wglGetCurrentContext() == hglrc) {'
            print '        gltrace::clearContext();'
            print '    }'
            print '    gltrace::releaseContext((uintptr_t)hglrc);'

        # Emit fake glBitmap calls in the trace on wglUseFontBitmapsA.
        # This enables to capture the real bitmaps and replay them outside Windows.
        #
        # XXX: In spite what
        # https://msdn.microsoft.com/en-us/library/windows/desktop/dd374392.aspx
        # implies, GetGlyphOutline(GGO_BITMAP) does not seem to work with
        # certain fonts.  The only solution is to draw the font charactors with
        # a HBITMAP like the old Mesa fxwgl.c code used to do.  That too, seems
        # to be the way that opengl32.dll implements wglUseFontBitmaps.
        #
        if function.name == 'wglUseFontBitmapsA':

            self.invokeFunction(function)

            # Emit a fake string marker with the original call
            print r'    {'
            print r'        std::ostringstream ss;'
            print r'        ss << __FUNCTION__ << "(hdc = " << hdc << ", first = " << first << ", count = " << count << ", listBase = " << listBase << ") = " << (_result ? "TRUE" : "FALSE");'
            print r'        _fakeStringMarker(ss.str());'
            print r'    }'
            print

            glNewList = glapi.getFunctionByName('glNewList')
            glBitmap = glapi.getFunctionByName('glBitmap')
            glEndList = glapi.getFunctionByName('glEndList')

            print r'    if (_result) {'

            print r'        HFONT hFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);'
            print r'        assert (hFont != nullptr);'
            print r'        LOGFONT lf;'
            print r'        if (GetObject(hFont, sizeof lf, &lf) != 0) {'
            print r'            std::ostringstream ss;'
            print r'            ss << "lfFaceName = " << lf.lfFaceName'
            print r'               << ", lfHeight = " << lf.lfHeight'
            print r'               << ", lfWeight = " << lf.lfWeight;'
            print r'            if (lf.lfItalic) ss << ", lfItalic = 1";'
            print r'            if (lf.lfUnderline) ss << ", lfUnderline = 1";'
            print r'            if (lf.lfStrikeOut) ss << ", lfStrikeOut = 1";'
            print r'            _fakeStringMarker(ss.str());'
            print r'        }'
            print

            print r'        BOOL bRet;'
            print r'        TEXTMETRIC tm;'
            print r'        bRet = GetTextMetricsA(hdc, &tm);'
            print r'        assert(bRet);'
            print
            print r'        HDC memDC = CreateCompatibleDC(hdc);'
            print
            print r'        SetMapMode(memDC, MM_TEXT);'
            print r'        SetTextAlign(memDC, TA_BASELINE);'
            print r'        SetBkColor(memDC, RGB(0, 0, 0));'
            print r'        SetBkMode(memDC, OPAQUE);'
            print r'        SetTextColor(memDC, RGB(255,255,255));'
            print
            print r'        BITMAPINFO * bmi = (BITMAPINFO *)malloc(offsetof(BITMAPINFO, bmiColors[2]));'
            print r'        ZeroMemory(&bmi->bmiHeader, sizeof bmi->bmiHeader);'
            print r'        bmi->bmiHeader.biSize = sizeof bmi->bmiHeader;'
            print r'        bmi->bmiHeader.biPlanes = 1;'
            print r'        bmi->bmiHeader.biBitCount = 1;'
            print r'        bmi->bmiHeader.biCompression = BI_RGB;'
            print r'        bmi->bmiColors[0].rgbBlue     = 0;'
            print r'        bmi->bmiColors[0].rgbGreen    = 0;'
            print r'        bmi->bmiColors[0].rgbRed      = 0;'
            print r'        bmi->bmiColors[0].rgbReserved = 0;'
            print r'        bmi->bmiColors[1].rgbBlue     = 255;'
            print r'        bmi->bmiColors[1].rgbGreen    = 255;'
            print r'        bmi->bmiColors[1].rgbRed      = 255;'
            print r'        bmi->bmiColors[1].rgbReserved = 0;'
            print
            print r'        for (DWORD i = 0; i < count; ++i) {'
            print r'            _fake_glNewList(listBase + i, GL_COMPILE);'
            print
            print r'            char cChar = first + i;'
            print
            print r'            // TODO: Use GetCharABSWidths'
            print r'            // http://www.codeproject.com/Articles/14915/Width-of-text-in-italic-font'
            print r'            // https://support.microsoft.com/en-us/kb/94646'
            print r'            SIZE size;'
            print r'            bRet = GetTextExtentPoint32A(hdc, &cChar, 1, &size);'
            print r'            if (bRet) {'
            print r'                assert(size.cx >= 0);'
            print r'                assert(size.cy >= 0);'
            print
            print r'                // Round width to 32 pixels'
            print r'                int nWidth = (size.cx + 0x1f) & ~0x1f;'
            print r'                int nHeight = size.cy;'
            print
            print r'                DWORD dwBytes = nWidth / 8 * nHeight;'
            print r'                LPVOID lpvBits = NULL;'
            print r'                if (dwBytes) {'
            print r'                    lpvBits = malloc(dwBytes);'
            print
            print r'                    HBITMAP memBM = CreateCompatibleBitmap(memDC, nWidth, nHeight);'
            print
            print r'                    HGDIOBJ origBM = SelectObject(memDC, memBM);'
            print
            print r'                    PatBlt(memDC, 0, 0, nWidth, nHeight, BLACKNESS);'
            print r'                    SelectObject(memDC, hFont);'
            print
            print r'                    bmi->bmiHeader.biWidth  = nWidth;'
            print r'                    bmi->bmiHeader.biHeight = nHeight;'
            print
            print r'                    bRet = TextOutA(memDC, 0, tm.tmAscent, &cChar, 1);'
            print r'                    assert(bRet);'
            print
            print r'                    SelectObject(memDC, origBM);'
            print
            print r'                    int nScanLines = GetDIBits(memDC, memBM, 0, nHeight, lpvBits, bmi, DIB_RGB_COLORS);'
            print r'                    assert(nScanLines == nHeight);'
            print
            print r'                    DeleteObject(memBM);'
            print r'                }'
            print
            print r'                GLsizei width  = nWidth;'
            print r'                GLfloat height = nHeight;'
            print r'                GLfloat xorig  = 0;'
            print r'                GLfloat yorig  = tm.tmDescent;'
            print r'                GLfloat xmove  = size.cx;'
            print r'                GLfloat ymove  = 0;'
            print r'                const GLubyte *bitmap = (const GLubyte *)lpvBits;'
            print r'                if (bitmap == NULL) {'
            print r'                    // We still need to emit an empty glBitmap for empty characters like spaces;'
            print r'                    width = height = xorig = yorig = 0;'
            print r'                }'

            # FIXME: glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
            # FIXME: glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
            print
            print r'                _fake_glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap);'
            print
            print r'                free(lpvBits);'
            print r'            }'
            print r'            _fake_glEndList();'
            print r'        }'
            print
            print r'        DeleteDC(memDC);'
            print r'        free(bmi);'

            print r'    } // _result'
            return

        GlTracer.traceFunctionImplBody(self, function)

        if function.name in self.createContextFunctionNames:
            print '    if (_result)'
            print '        gltrace::createContext((uintptr_t)_result);'

        if function.name in self.makeCurrentFunctionNames:
            print '    if (_result) {'
            print '        if (hglrc != NULL)'
            print '            gltrace::setContext((uintptr_t)hglrc);'
            print '        else'
            print '            gltrace::clearContext();'
            print '    }'