Changeset 48275 in vbox for trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp
- Timestamp:
- Sep 4, 2013 4:23:11 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp
r46885 r48275 28 28 #include <iprt/mem.h> 29 29 30 31 30 /* @param pCtxBase - contains the blitter context info. Its value is treated differently depending on the fCreateNewCtx value 32 31 * @param fCreateNewCtx - if true - the pCtxBase must NOT be NULL. its visualBits is used as a visual bits info for the new context, … … 47 46 * This is needed because BlitFramebufferEXT is known to be often buggy, and glDrawXxx-based blits appear to be more reliable 48 47 */ 49 int CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, SPUDispatchTable *pDispatch)48 VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, const CR_GLSL_CACHE *pShaders, SPUDispatchTable *pDispatch) 50 49 { 51 50 if (pCtxBase && pCtxBase->Base.id < 0) … … 80 79 pBlitter->Flags.CtxCreated = 1; 81 80 } 81 82 if (pShaders) 83 { 84 pBlitter->pGlslCache = pShaders; 85 pBlitter->Flags.ShadersGloal = 1; 86 } 87 else 88 { 89 CrGlslInit(&pBlitter->LocalGlslCache, pDispatch); 90 pBlitter->pGlslCache = &pBlitter->LocalGlslCache; 91 } 92 93 return VINF_SUCCESS; 94 } 95 96 VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural) 97 { 98 if (CrBltIsEntered(pBlitter)) 99 { 100 crWarning("CrBltBlitTexTex: blitter is entered"); 101 return VERR_INVALID_STATE; 102 } 103 104 if (pBlitter->Flags.ShadersGloal || !CrGlslNeedsCleanup(&pBlitter->LocalGlslCache)) 105 return VINF_SUCCESS; 106 107 int rc = CrBltEnter(pBlitter, pRestoreCtxInfo, pRestoreMural); 108 if (!RT_SUCCESS(rc)) 109 { 110 crWarning("CrBltEnter failed, rc %d"); 111 return rc; 112 } 113 114 CrGlslCleanup(&pBlitter->LocalGlslCache); 115 116 CrBltLeave(pBlitter); 82 117 83 118 return VINF_SUCCESS; … … 596 631 crBltCheckSetupViewport(pBlitter, pDstSize, enmDstBuff == GL_DRAW_FRAMEBUFFER); 597 632 598 pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags); 633 if (!(fFlags & CRBLT_F_NOALPHA)) 634 pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags); 635 else 636 { 637 int rc = pBlitter->Flags.ShadersGloal ? 638 CrGlslProgUseNoAlpha(pBlitter->pGlslCache, pSrc->target) 639 : 640 CrGlslProgUseGenNoAlpha(&pBlitter->LocalGlslCache, pSrc->target); 641 642 if (!RT_SUCCESS(rc)) 643 { 644 crWarning("Failed to use no-alpha program rc!, falling back to default blit", rc); 645 pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags); 646 return; 647 } 648 649 /* since we use shaders, we need to use draw commands rather than framebuffer blits. 650 * force using draw-based blitting */ 651 crBltBlitTexBufImplDraw2D(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags); 652 653 Assert(pBlitter->Flags.ShadersGloal || &pBlitter->LocalGlslCache == pBlitter->pGlslCache); 654 655 CrGlslProgClear(pBlitter->pGlslCache); 656 } 599 657 } 600 658 … … 760 818 } 761 819 820 821 VBOXBLITTERDECL(bool) CrGlslIsSupported(CR_GLSL_CACHE *pCache) 822 { 823 if (pCache->glVersion == 0.) 824 { 825 const char * pszStr = (const char*)pCache->pDispatch->GetString(GL_VERSION); 826 pCache->glVersion = crStrToFloat(pszStr); 827 if (pCache->glVersion == 0.) 828 { 829 crWarning("pCache->glVersion is null!"); 830 } 831 } 832 833 if (pCache->glVersion >= 2.0) 834 return true; 835 836 /* @todo: we could also check for GL_ARB_shader_objects and GL_ARB_fragment_shader, 837 * but seems like chromium does not support properly gl*Object versions of shader functions used with those extensions */ 838 return false; 839 } 840 841 #define CR_GLSL_STR_V_120 "#version 120\n" 842 #define CR_GLSL_STR_EXT_TR "#extension GL_ARB_texture_rectangle : enable\n" 843 #define CR_GLSL_STR_TEX2D "texture2D" 844 #define CR_GLSL_STR_TEX2DRECT "texture2DRect" 845 846 #define CR_GLSL_PATTERN_FS_NOALPHA(_ver, _ext, _tex) \ 847 _ver \ 848 _ext \ 849 "void main()\n" \ 850 "{\n" \ 851 "vec2 srcCoord = vec2(gl_TexCoord[0]);\n" \ 852 "gl_FragData[0].xyz = (" _tex "(0, srcCoord).xyz);\n" \ 853 "gl_FragData[0].w = 1.0;\n" \ 854 "}\n" 855 856 static const char* crGlslGetFsStringNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 857 { 858 if (!CrGlslIsSupported(pCache)) 859 { 860 crWarning("CrGlslIsSupported is false"); 861 return NULL; 862 } 863 864 if (pCache->glVersion >= 2.1) 865 { 866 if (enmTexTarget == GL_TEXTURE_2D) 867 return CR_GLSL_PATTERN_FS_NOALPHA(CR_GLSL_STR_V_120, "", CR_GLSL_STR_TEX2D); 868 else if (enmTexTarget == GL_TEXTURE_RECTANGLE_ARB) 869 return CR_GLSL_PATTERN_FS_NOALPHA(CR_GLSL_STR_V_120, CR_GLSL_STR_EXT_TR, CR_GLSL_STR_TEX2DRECT); 870 871 crWarning("invalid enmTexTarget %#x", enmTexTarget); 872 return NULL; 873 } 874 else if (pCache->glVersion >= 2.0) 875 { 876 if (enmTexTarget == GL_TEXTURE_2D) 877 return CR_GLSL_PATTERN_FS_NOALPHA("", "", CR_GLSL_STR_TEX2D); 878 else if (enmTexTarget == GL_TEXTURE_RECTANGLE_ARB) 879 return CR_GLSL_PATTERN_FS_NOALPHA("", CR_GLSL_STR_EXT_TR, CR_GLSL_STR_TEX2DRECT); 880 881 crWarning("invalid enmTexTarget %#x", enmTexTarget); 882 return NULL; 883 } 884 885 crError("crGlslGetFsStringNoAlpha: we should not be here!"); 886 return NULL; 887 } 888 889 static int crGlslProgGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget, GLuint *puiProgram) 890 { 891 *puiProgram = 0; 892 893 const char*pStrFsShader = crGlslGetFsStringNoAlpha(pCache, enmTexTarget); 894 if (!pStrFsShader) 895 { 896 crWarning("crGlslGetFsStringNoAlpha failed"); 897 return VERR_NOT_SUPPORTED; 898 } 899 900 int rc = VINF_SUCCESS; 901 GLchar * pBuf = NULL; 902 GLuint uiProgram = 0; 903 GLuint uiShader = pCache->pDispatch->CreateShader(GL_FRAGMENT_SHADER); 904 if (!uiShader) 905 { 906 crWarning("CreateShader failed"); 907 return VERR_NOT_SUPPORTED; 908 } 909 910 pCache->pDispatch->ShaderSource(uiShader, 1, &pStrFsShader, NULL); 911 912 pCache->pDispatch->CompileShader(uiShader); 913 914 GLint compiled = 0; 915 pCache->pDispatch->GetShaderiv(uiShader, GL_COMPILE_STATUS, &compiled); 916 917 #ifdef DEBUG_misha 918 if(!compiled) 919 #endif 920 { 921 if (!pBuf) 922 pBuf = (GLchar *)RTMemAlloc(16300); 923 pCache->pDispatch->GetShaderInfoLog(uiShader, 16300, NULL, pBuf); 924 #ifdef DEBUG_misha 925 if (compiled) 926 crDebug("compile success:\n-------------------\n%d\n--------\n", pBuf); 927 else 928 #endif 929 { 930 crWarning("compile FAILURE:\n-------------------\n%d\n--------\n", pBuf); 931 rc = VERR_NOT_SUPPORTED; 932 goto end; 933 } 934 } 935 936 Assert(compiled); 937 938 uiProgram = pCache->pDispatch->CreateProgram(); 939 if (!uiProgram) 940 { 941 rc = VERR_NOT_SUPPORTED; 942 goto end; 943 } 944 945 pCache->pDispatch->AttachShader(uiProgram, uiShader); 946 947 pCache->pDispatch->LinkProgram(uiProgram); 948 949 GLint linked; 950 pCache->pDispatch->GetProgramiv(uiProgram, GL_LINK_STATUS, &linked); 951 #ifdef DEBUG_misha 952 if(!linked) 953 #endif 954 { 955 if (!pBuf) 956 pBuf = (GLchar *)RTMemAlloc(16300); 957 pCache->pDispatch->GetProgramInfoLog(uiProgram, 16300, NULL, pBuf); 958 #ifdef DEBUG_misha 959 if (linked) 960 crDebug("link success:\n-------------------\n%d\n--------\n", pBuf); 961 else 962 #endif 963 { 964 crWarning("link FAILURE:\n-------------------\n%d\n--------\n", pBuf); 965 rc = VERR_NOT_SUPPORTED; 966 goto end; 967 } 968 } 969 970 Assert(linked); 971 972 *puiProgram = uiProgram; 973 974 /* avoid end finalizer from cleaning it */ 975 uiProgram = 0; 976 977 end: 978 if (uiShader) 979 pCache->pDispatch->DeleteShader(uiShader); 980 if (uiProgram) 981 pCache->pDispatch->DeleteProgram(uiProgram); 982 if (pBuf) 983 RTMemFree(pBuf); 984 return rc; 985 } 986 987 DECLINLINE(GLuint) crGlslProgGetNoAlpha(const CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 988 { 989 switch (enmTexTarget) 990 { 991 case GL_TEXTURE_2D: 992 return pCache->uNoAlpha2DProg; 993 case GL_TEXTURE_RECTANGLE_ARB: 994 return pCache->uNoAlpha2DRectProg; 995 default: 996 crWarning("invalid tex enmTexTarget %#x", enmTexTarget); 997 return 0; 998 } 999 } 1000 1001 DECLINLINE(GLuint*) crGlslProgGetNoAlphaPtr(CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 1002 { 1003 switch (enmTexTarget) 1004 { 1005 case GL_TEXTURE_2D: 1006 return &pCache->uNoAlpha2DProg; 1007 case GL_TEXTURE_RECTANGLE_ARB: 1008 return &pCache->uNoAlpha2DRectProg; 1009 default: 1010 crWarning("invalid tex enmTexTarget %#x", enmTexTarget); 1011 return NULL; 1012 } 1013 } 1014 1015 VBOXBLITTERDECL(int) CrGlslProgGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 1016 { 1017 GLuint*puiProgram = crGlslProgGetNoAlphaPtr(pCache, enmTexTarget); 1018 if (!puiProgram) 1019 return VERR_INVALID_PARAMETER; 1020 1021 if (*puiProgram) 1022 return VINF_SUCCESS; 1023 1024 return crGlslProgGenNoAlpha(pCache, enmTexTarget, puiProgram); 1025 } 1026 1027 VBOXBLITTERDECL(int) CrGlslProgGenAllNoAlpha(CR_GLSL_CACHE *pCache) 1028 { 1029 int rc = CrGlslProgGenNoAlpha(pCache, GL_TEXTURE_2D); 1030 if (!RT_SUCCESS(rc)) 1031 { 1032 crWarning("CrGlslProgGenNoAlpha GL_TEXTURE_2D failed rc %d", rc); 1033 return rc; 1034 } 1035 1036 rc = CrGlslProgGenNoAlpha(pCache, GL_TEXTURE_RECTANGLE_ARB); 1037 if (!RT_SUCCESS(rc)) 1038 { 1039 crWarning("CrGlslProgGenNoAlpha GL_TEXTURE_RECTANGLE failed rc %d", rc); 1040 return rc; 1041 } 1042 1043 return VINF_SUCCESS; 1044 } 1045 1046 VBOXBLITTERDECL(void) CrGlslProgClear(const CR_GLSL_CACHE *pCache) 1047 { 1048 pCache->pDispatch->UseProgram(0); 1049 } 1050 1051 VBOXBLITTERDECL(int) CrGlslProgUseNoAlpha(const CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 1052 { 1053 GLuint uiProg = crGlslProgGetNoAlpha(pCache, enmTexTarget); 1054 if (!uiProg) 1055 { 1056 crWarning("request to use inexistent program!"); 1057 return VERR_INVALID_STATE; 1058 } 1059 1060 Assert(uiProg); 1061 1062 pCache->pDispatch->UseProgram(uiProg); 1063 1064 return VINF_SUCCESS; 1065 } 1066 1067 VBOXBLITTERDECL(int) CrGlslProgUseGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget) 1068 { 1069 GLuint uiProg = crGlslProgGetNoAlpha(pCache, enmTexTarget); 1070 if (!uiProg) 1071 { 1072 int rc = CrGlslProgGenNoAlpha(pCache, enmTexTarget); 1073 if (!RT_SUCCESS(rc)) 1074 { 1075 crWarning("CrGlslProgGenNoAlpha failed, rc %d", rc); 1076 return rc; 1077 } 1078 1079 uiProg = crGlslProgGetNoAlpha(pCache, enmTexTarget); 1080 CRASSERT(uiProg); 1081 } 1082 1083 Assert(uiProg); 1084 1085 pCache->pDispatch->UseProgram(uiProg); 1086 1087 return VINF_SUCCESS; 1088 } 1089 1090 VBOXBLITTERDECL(bool) CrGlslNeedsCleanup(CR_GLSL_CACHE *pCache) 1091 { 1092 return pCache->uNoAlpha2DProg || pCache->uNoAlpha2DRectProg; 1093 } 1094 1095 VBOXBLITTERDECL(void) CrGlslCleanup(CR_GLSL_CACHE *pCache) 1096 { 1097 if (pCache->uNoAlpha2DProg) 1098 { 1099 pCache->pDispatch->DeleteProgram(pCache->uNoAlpha2DProg); 1100 pCache->uNoAlpha2DProg = 0; 1101 } 1102 1103 if (pCache->uNoAlpha2DRectProg) 1104 { 1105 pCache->pDispatch->DeleteProgram(pCache->uNoAlpha2DRectProg); 1106 pCache->uNoAlpha2DRectProg = 0; 1107 } 1108 } 1109 1110 VBOXBLITTERDECL(void) CrGlslTerm(CR_GLSL_CACHE *pCache) 1111 { 1112 CRASSERT(!CrGlslNeedsCleanup(pCache)); 1113 1114 CrGlslCleanup(pCache); 1115 1116 /* sanity */ 1117 memset(pCache, 0, sizeof (*pCache)); 1118 }
Note:
See TracChangeset
for help on using the changeset viewer.