- Timestamp:
- Aug 17, 2018 1:51:09 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 124417
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
r73633 r73736 2802 2802 } 2803 2803 2804 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)2805 {2806 PVMSVGA3DSTATE pState = pThis->svga.p3dState;2807 PVMSVGA3DSURFACE pSurface;2808 PVMSVGA3DCONTEXT pContext;2809 uint32_t cid;2810 2811 AssertReturn(pState, VERR_NO_MEMORY);2812 AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);2813 AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);2814 2815 pSurface = pState->papSurfaces[sid];2816 2817 Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects));2818 for (uint32_t i=0; i < cRects; i++)2819 Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));2820 2821 pContext = &pState->SharedCtx;2822 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);2823 cid = pContext->id;2824 VMSVGA3D_CLEAR_GL_ERRORS();2825 2826 #if 0 /* Can't make sense of this. SVGA3dCopyRect doesn't allow scaling. non-blit-cube path change to not use it. */2827 /*2828 * Source surface different size?2829 */2830 RTRECT2 srcViewPort;2831 if ( pSurface->pMipmapLevels[0].size.width != pThis->svga.uWidth2832 || pSurface->pMipmapLevels[0].size.height != pThis->svga.uHeight)2833 {2834 float xMultiplier = (float)pSurface->pMipmapLevels[0].size.width / (float)pThis->svga.uWidth;2835 float yMultiplier = (float)pSurface->pMipmapLevels[0].size.height / (float)pThis->svga.uHeight;2836 2837 LogFlow(("size (%d vs %d, %d vs %d) multiplier (" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",2838 pSurface->pMipmapLevels[0].size.width, pThis->svga.uWidth,2839 pSurface->pMipmapLevels[0].size.height, pThis->svga.uHeight,2840 FLOAT_FMT_ARGS(xMultiplier), FLOAT_FMT_ARGS(yMultiplier) ));2841 2842 srcViewPort.x = (uint32_t)((float)pThis->svga.viewport.x * xMultiplier);2843 srcViewPort.y = (uint32_t)((float)pThis->svga.viewport.y * yMultiplier);2844 srcViewPort.cx = (uint32_t)((float)pThis->svga.viewport.cx * xMultiplier);2845 srcViewPort.cy = (uint32_t)((float)pThis->svga.viewport.cy * yMultiplier);2846 }2847 else2848 {2849 srcViewPort.x = pThis->svga.viewport.x;2850 srcViewPort.y = pThis->svga.viewport.y;2851 srcViewPort.cx = pThis->svga.viewport.cx;2852 srcViewPort.cy = pThis->svga.viewport.cy;2853 }2854 RTRECT SrcViewPortRect;2855 SrcViewPortRect.xLeft = srcViewPort.x;2856 SrcViewPortRect.xRight = srcViewPort.x + srcViewPort.cx;2857 SrcViewPortRect.yBottom = srcViewPort.y;2858 SrcViewPortRect.yTop = srcViewPort.y + srcViewPort.cy;2859 #endif2860 2861 2862 #if 0//ndef RT_OS_DARWIN /* blit-cube fails in this path... */2863 /*2864 * Note! this path is slightly faster than the glBlitFrameBuffer path below.2865 */2866 SVGA3dCopyRect rect;2867 uint32_t oldVShader, oldPShader;2868 GLint oldTextureId;2869 2870 if (cRects == 0)2871 {2872 rect.x = rect.y = rect.srcx = rect.srcy = 0;2873 rect.w = pSurface->pMipmapLevels[0].size.width;2874 rect.h = pSurface->pMipmapLevels[0].size.height;2875 pRect = ▭2876 cRects = 1;2877 }2878 2879 //glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);2880 2881 #if 02882 glDisable(GL_CULL_FACE);2883 glDisable(GL_BLEND);2884 glDisable(GL_ALPHA_TEST);2885 glDisable(GL_SCISSOR_TEST);2886 glDisable(GL_STENCIL_TEST);2887 glEnable(GL_DEPTH_TEST);2888 glDepthFunc(GL_ALWAYS);2889 glDepthMask(GL_TRUE);2890 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);2891 glViewport(0, 0, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height);2892 #endif2893 2894 VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureId), pState, pContext);2895 2896 oldVShader = pContext->state.shidVertex;2897 oldPShader = pContext->state.shidPixel;2898 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, SVGA_ID_INVALID);2899 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, SVGA_ID_INVALID);2900 2901 /* Flush shader changes. */2902 if (pContext->pShaderContext)2903 ShaderUpdateState(pContext->pShaderContext, 0);2904 2905 /* Activate the read and draw framebuffer objects. */2906 VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer), pState, pContext);2907 VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */), pState, pContext);2908 2909 VMSVGA3D_ASSERT_GL_CALL(pState->ext.glActiveTexture(GL_TEXTURE0), pState, pContext);2910 VMSVGA3D_ASSERT_GL_CALL(glEnable(GL_TEXTURE_2D), pState, pContext);;2911 VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture), pState, pContext);2912 2913 VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR), pState, pContext);2914 VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR), pState, pContext);;2915 2916 #if 02917 VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP), pState, pContext);;2918 VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP), pState, pContext);;2919 #endif2920 2921 /* Reset the transformation matrices. */2922 VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);2923 VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);2924 VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);2925 VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);2926 VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);2927 VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);2928 VMSVGA3D_ASSERT_GL_CALL(glScalef(1.0f, -1.0f, 1.0f), pState, pContext);2929 VMSVGA3D_ASSERT_GL_CALL(glOrtho(0, pThis->svga.uWidth, pThis->svga.uHeight, 0, 0.0, -1.0), pState, pContext);2930 2931 for (uint32_t i = 0; i < cRects; i++)2932 {2933 float left, right, top, bottom; /* Texture coordinates */2934 int vertexLeft, vertexRight, vertexTop, vertexBottom;2935 2936 pRect[i].srcx = RT_MAX(pRect[i].srcx, (uint32_t)RT_MAX(srcViewPort.x, 0));2937 pRect[i].srcy = RT_MAX(pRect[i].srcy, (uint32_t)RT_MAX(srcViewPort.y, 0));2938 pRect[i].x = RT_MAX(pRect[i].x, pThis->svga.viewport.x) - pThis->svga.viewport.x;2939 pRect[i].y = RT_MAX(pRect[i].y, pThis->svga.viewport.y) - pThis->svga.viewport.y;2940 pRect[i].w = pThis->svga.viewport.cx;2941 pRect[i].h = pThis->svga.viewport.cy;2942 2943 if ( pRect[i].x + pRect[i].w <= pThis->svga.viewport.x2944 || pThis->svga.viewport.x + pThis->svga.viewport.cx <= pRect[i].x2945 || pRect[i].y + pRect[i].h <= pThis->svga.viewport.y2946 || pThis->svga.viewport.y + pThis->svga.viewport.cy <= pRect[i].y)2947 {2948 /* Intersection is empty; skip */2949 continue;2950 }2951 2952 left = pRect[i].srcx;2953 right = pRect[i].srcx + pRect[i].w;2954 top = pRect[i].srcy + pRect[i].h;2955 bottom = pRect[i].srcy;2956 2957 left /= pSurface->pMipmapLevels[0].size.width;2958 right /= pSurface->pMipmapLevels[0].size.width;2959 top /= pSurface->pMipmapLevels[0].size.height;2960 bottom /= pSurface->pMipmapLevels[0].size.height;2961 2962 vertexLeft = pRect[i].x;2963 vertexRight = pRect[i].x + pRect[i].w;2964 vertexTop = ((uint32_t)pThis->svga.uHeight >= pRect[i].y + pRect[i].h) ? pThis->svga.uHeight - pRect[i].y - pRect[i].h : 0;2965 vertexBottom = pThis->svga.uHeight - pRect[i].y;2966 2967 Log(("view port (%d,%d)(%d,%d)\n", srcViewPort.x, srcViewPort.y, srcViewPort.cx, srcViewPort.cy));2968 Log(("vertex (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", vertexLeft, vertexBottom, vertexLeft, vertexTop, vertexRight, vertexTop, vertexRight, vertexBottom));2969 Log(("texture (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h), pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h)));2970 2971 glBegin(GL_QUADS);2972 2973 /* bottom left */2974 glTexCoord2f(left, bottom);2975 glVertex2i(vertexLeft, vertexBottom);2976 2977 /* top left */2978 glTexCoord2f(left, top);2979 glVertex2i(vertexLeft, vertexTop);2980 2981 /* top right */2982 glTexCoord2f(right, top);2983 glVertex2i(vertexRight, vertexTop);2984 2985 /* bottom right */2986 glTexCoord2f(right, bottom);2987 glVertex2i(vertexRight, vertexBottom);2988 2989 VMSVGA3D_ASSERT_GL_CALL(glEnd(), pState, pContext);2990 }2991 2992 /* Restore old settings. */2993 VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);2994 VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);2995 VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);2996 VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);2997 2998 //VMSVGA3D_ASSERT_GL_CALL(glPopAttrib(), pState, pContext);2999 3000 VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, oldTextureId), pState, pContext);3001 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, oldVShader);3002 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, oldPShader);3003 3004 #else3005 /*3006 * glBlitFramebuffer variant.3007 */3008 /* Activate the read and draw framebuffer objects. */3009 pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer);3010 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);3011 pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */);3012 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);3013 3014 /* Bind the source objects to the right place. */3015 Assert(pSurface->targetGL == GL_TEXTURE_2D);3016 pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurface->oglId.texture, 0 /* level 0 */);3017 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);3018 3019 3020 /* Read the destination viewport specs in one go to try avoid some unnecessary update races. */3021 VMSVGAVIEWPORT const DstViewport = pThis->svga.viewport;3022 ASMCompilerBarrier(); /* paranoia */3023 Assert(DstViewport.yHighWC >= DstViewport.yLowWC);3024 3025 /* If there are no recangles specified, just grab a screenful. */3026 SVGA3dCopyRect DummyRect;3027 if (cRects != 0)3028 { /* likely */ }3029 else3030 {3031 /** @todo Find the usecase for this or check what the original device does.3032 * The original code was doing some scaling based on the surface3033 * size... */3034 # ifdef DEBUG_bird3035 AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n"));3036 # endif3037 DummyRect.x = DummyRect.srcx = 0;3038 DummyRect.y = DummyRect.srcy = 0;3039 DummyRect.w = pThis->svga.uWidth;3040 DummyRect.h = pThis->svga.uHeight;3041 cRects = 1;3042 pRect = &DummyRect;3043 }3044 3045 /*3046 * Blit the surface rectangle(s) to the back buffer.3047 */3048 uint32_t const cxSurface = pSurface->pMipmapLevels[0].mipmapSize.width;3049 uint32_t const cySurface = pSurface->pMipmapLevels[0].mipmapSize.height;3050 for (uint32_t i = 0; i < cRects; i++)3051 {3052 SVGA3dCopyRect ClippedRect = pRect[i];3053 3054 /*3055 * Do some sanity checking and limit width and height, all so we3056 * don't need to think about wrap-arounds below.3057 */3058 if (RT_LIKELY( ClippedRect.w3059 && ClippedRect.x < VMSVGA_MAX_X3060 && ClippedRect.srcx < VMSVGA_MAX_X3061 && ClippedRect.h3062 && ClippedRect.y < VMSVGA_MAX_Y3063 && ClippedRect.srcy < VMSVGA_MAX_Y3064 ))3065 { /* likely */ }3066 else3067 continue;3068 3069 if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_X))3070 { /* likely */ }3071 else3072 ClippedRect.w = VMSVGA_MAX_X;3073 if (RT_LIKELY(ClippedRect.h < VMSVGA_MAX_Y))3074 { /* likely */ }3075 else3076 ClippedRect.h = VMSVGA_MAX_Y;3077 3078 3079 /*3080 * Source surface clipping (paranoia). Straight forward.3081 */3082 if (RT_LIKELY(ClippedRect.srcx < cxSurface))3083 { /* likely */ }3084 else3085 continue;3086 if (RT_LIKELY(ClippedRect.srcx + ClippedRect.w <= cxSurface))3087 { /* likely */ }3088 else3089 {3090 AssertFailed(); /* remove if annoying. */3091 ClippedRect.w = cxSurface - ClippedRect.srcx;3092 }3093 3094 if (RT_LIKELY(ClippedRect.srcy < cySurface))3095 { /* likely */ }3096 else3097 continue;3098 if (RT_LIKELY(ClippedRect.srcy + ClippedRect.h <= cySurface))3099 { /* likely */ }3100 else3101 {3102 AssertFailed(); /* remove if annoying. */3103 ClippedRect.h = cySurface - ClippedRect.srcy;3104 }3105 3106 /*3107 * Destination viewport clipping - real PITA.3108 *3109 * We have to take the following into account here:3110 * - The source image is Y inverted.3111 * - The destination framebuffer is in world and not window coordinates,3112 * just like the source surface. This means working in the first quadrant.3113 * - The viewport is in window coordinate, that is fourth quadrant and3114 * negated Y values.3115 * - The destination framebuffer is not scrolled, so we have to blit3116 * what's visible into the top of the framebuffer.3117 *3118 *3119 * To illustrate:3120 *3121 * source destination 01234567893122 * 8 ^---------- 8 ^---------- 0 ----------->3123 * 7 | | 7 | | 1 | |3124 * 6 | | 6 | ******* | 2 | ******* |3125 * 5 | *** | 5 | * | 3 | * |3126 * 4 | * | => 4 | * | => 4 | * |3127 * 3 | * | 3 | *** | 5 | *** |3128 * 2 | ******* | 2 | | 6 | |3129 * 1 | | 1 | | 7 | |3130 * 0 -----------> 0 -----------> 8 v----------3131 * 0123456789 0123456789 Destination window3132 *3133 * From the above, it follows that a destination viewport given in3134 * window coordinates matches the source exactly when srcy = srcx = 0.3135 *3136 * Example (Y only):3137 * ySrc = 03138 * yDst = 03139 * cyCopy = 93140 * cyScreen = cyCopy3141 * cySurface >= cyCopy3142 * yViewport = 53143 * cyViewport = 2 (i.e. '| *** |'3144 * '| |' )3145 * yWCViewportHi = cxScreen - yViewport = 9 - 5 = 43146 * yWCViewportLow = cxScreen - yViewport - cyViewport = 4 - 2 = 23147 *3148 * We can see from the illustration that the final result should be:3149 * SrcRect = (0,7) (11, 5) (cy=2 from y=5)3150 * DstRect = (0,2) (11, 4)3151 *3152 * Let's postpone the switching of SrcRect.yBottom/yTop to make it3153 * easier to follow:3154 * SrcRect = (0,5) (11, 7)3155 *3156 * From the top, Y values only:3157 * 0. Copy = { .yDst = 0, .ySrc = 0, .cy = 9 }3158 *3159 * 1. CopyRect.yDst (=0) is lower than yWCViewportLow:3160 * cyAdjust = yWCViewportLow - CopyRect.yDst = 2;3161 * Copy.yDst += cyAdjust = 2;3162 * Copy.ySrc = unchanged;3163 * Copy.cx -= cyAdjust = 7;3164 * => Copy = { .yDst = 2, .ySrc = 0, .cy = 7 }3165 *3166 * 2. CopyRect.yDst + CopyRect.cx (=9) is higher than yWCViewportHi:3167 * cyAdjust = CopyRect.yDst + CopyRect.cx - yWCViewportHi = 9 - 4 = 53168 * Copy.yDst = unchanged;3169 * Copy.ySrc += cyAdjust = 5;3170 * Copy.cx -= cyAdjust = 2;3171 * => Copy = { .yDst = 2, .ySrc = 5, .cy = 2 }3172 *3173 * Update: On darwin, it turns out that when we call [NSOpenGLContext updates]3174 * when the view is resized, moved and otherwise messed with,3175 * the visible part of the framebuffer is actually the bottom3176 * one. It's easy to adjust for this, just have to adjust the3177 * destination rectangle such that yBottom is zero.3178 */3179 /* X - no inversion, so kind of simple. */3180 if (ClippedRect.x >= DstViewport.x)3181 {3182 if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)3183 { /* typical */ }3184 else if (ClippedRect.x < DstViewport.xRight)3185 ClippedRect.w = DstViewport.xRight - ClippedRect.x;3186 else3187 continue;3188 }3189 else3190 {3191 uint32_t cxAdjust = DstViewport.x - ClippedRect.x;3192 if (cxAdjust < ClippedRect.w)3193 {3194 ClippedRect.w -= cxAdjust;3195 ClippedRect.x += cxAdjust;3196 ClippedRect.srcx += cxAdjust;3197 }3198 else3199 continue;3200 3201 if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)3202 { /* typical */ }3203 else3204 ClippedRect.w = DstViewport.xRight - ClippedRect.x;3205 }3206 3207 /* Y - complicated, see above. */3208 if (ClippedRect.y >= DstViewport.yLowWC)3209 {3210 if (ClippedRect.y + ClippedRect.h <= DstViewport.yHighWC)3211 { /* typical */ }3212 else if (ClippedRect.y < DstViewport.yHighWC)3213 {3214 /* adjustment #2 */3215 uint32_t cyAdjust = ClippedRect.y + ClippedRect.h - DstViewport.yHighWC;3216 ClippedRect.srcy += cyAdjust;3217 ClippedRect.h -= cyAdjust;3218 }3219 else3220 continue;3221 }3222 else3223 {3224 /* adjustment #1 */3225 uint32_t cyAdjust = DstViewport.yLowWC - ClippedRect.y;3226 if (cyAdjust < ClippedRect.h)3227 {3228 ClippedRect.y += cyAdjust;3229 ClippedRect.h -= cyAdjust;3230 }3231 else3232 continue;3233 3234 if (ClippedRect.y + ClippedRect.h <= DstViewport.yHighWC)3235 { /* typical */ }3236 else3237 {3238 /* adjustment #2 */3239 cyAdjust = ClippedRect.y + ClippedRect.h - DstViewport.yHighWC;3240 ClippedRect.srcy += cyAdjust;3241 ClippedRect.h -= cyAdjust;3242 }3243 }3244 3245 /* Calc source rectangle with y flipping wrt destination. */3246 RTRECT SrcRect;3247 SrcRect.xLeft = ClippedRect.srcx;3248 SrcRect.xRight = ClippedRect.srcx + ClippedRect.w;3249 SrcRect.yBottom = ClippedRect.srcy + ClippedRect.h;3250 SrcRect.yTop = ClippedRect.srcy;3251 3252 /* Calc destination rectangle. */3253 RTRECT DstRect;3254 DstRect.xLeft = ClippedRect.x;3255 DstRect.xRight = ClippedRect.x + ClippedRect.w;3256 DstRect.yBottom = ClippedRect.y;3257 DstRect.yTop = ClippedRect.y + ClippedRect.h;3258 3259 /* Adjust for viewport. */3260 DstRect.xLeft -= DstViewport.x;3261 DstRect.xRight -= DstViewport.x;3262 # ifdef RT_OS_DARWIN /* We actually seeing the bottom of the FB, not the top as on windows and X11. */3263 DstRect.yTop -= DstRect.yBottom;3264 DstRect.yBottom = 0;3265 # else3266 DstRect.yBottom += DstViewport.y;3267 DstRect.yTop += DstViewport.y;3268 # endif3269 3270 Log(("SrcRect: (%d,%d)(%d,%d) DstRect: (%d,%d)(%d,%d)\n",3271 SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,3272 DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop));3273 pState->ext.glBlitFramebuffer(SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,3274 DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop,3275 GL_COLOR_BUFFER_BIT, GL_LINEAR);3276 }3277 3278 #endif3279 3280 /*3281 * Flip the front and back buffers.3282 */3283 #ifdef RT_OS_WINDOWS3284 BOOL fRef = SwapBuffers(pContext->hdc);3285 AssertMsg(fRef, ("SwapBuffers failed with %d\n", GetLastError())); NOREF(fRef);3286 #elif defined(RT_OS_DARWIN)3287 vmsvga3dCocoaSwapBuffers(pContext->cocoaView, pContext->cocoaContext);3288 #else3289 /* show the window if not already done */3290 if (!pContext->fMapped)3291 {3292 XMapWindow(pState->display, pContext->window);3293 pContext->fMapped = true;3294 }3295 /* now swap the buffers, i.e. display the rendering result */3296 glXSwapBuffers(pState->display, pContext->window);3297 #endif3298 3299 /*3300 * Now we can reset the frame buffer association. Doing it earlier means no3301 * output on darwin.3302 */3303 VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer), pState, pContext);3304 return VINF_SUCCESS;3305 }3306 2804 3307 2805 #ifdef RT_OS_LINUX … … 3432 2930 3433 2931 #ifdef RT_OS_WINDOWS 3434 /* Create a context window. */ 2932 /* Create a context window with minimal 4x4 size. We will never use the swapchain 2933 * to present the rendered image. Rendered images from the guest will be copied to 2934 * the VMSVGA SCREEN object, which can be either an offscreen render target or 2935 * system memory in the guest VRAM. 2936 */ 3435 2937 CREATESTRUCT cs; 3436 2938 cs.lpCreateParams = NULL; 3437 cs.dwExStyle = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT;2939 cs.dwExStyle = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY; 3438 2940 # ifdef DEBUG_GFX_WINDOW 3439 2941 cs.lpszName = (char *)RTMemAllocZ(256); … … 3446 2948 cs.style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_CAPTION; 3447 2949 # else 3448 cs.style = WS_ CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | WS_CHILD | WS_VISIBLE;2950 cs.style = WS_DISABLED | WS_CHILD; 3449 2951 # endif 3450 2952 cs.x = 0; 3451 2953 cs.y = 0; 3452 cs.cx = pThis->svga.uWidth;3453 cs.cy = pThis->svga.uHeight;2954 cs.cx = 4; 2955 cs.cy = 4; 3454 2956 cs.hwndParent = (HWND)pThis->svga.u64HostWindowId; 3455 2957 cs.hMenu = NULL; … … 3466 2968 1, /* version number */ 3467 2969 PFD_DRAW_TO_WINDOW | /* support window */ 3468 PFD_DOUBLEBUFFER | /* support double buffering */3469 2970 PFD_SUPPORT_OPENGL, /* support OpenGL */ 3470 2971 PFD_TYPE_RGBA, /* RGBA type */ -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
r73297 r73736 2460 2460 } 2461 2461 2462 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)2463 {2464 PVMSVGA3DSTATE pState = pThis->svga.p3dState;2465 PVMSVGA3DSURFACE pSurface;2466 PVMSVGA3DCONTEXT pContext;2467 HRESULT hr;2468 int rc;2469 IDirect3DSurface9 *pBackBuffer;2470 IDirect3DSurface9 *pSurfaceD3D;2471 2472 AssertReturn(pState, VERR_NO_MEMORY);2473 2474 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);2475 AssertRCReturn(rc, rc);2476 2477 AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);2478 2479 LogFunc(("sid=%x cRects=%d cid=%x\n", sid, cRects, pSurface->idAssociatedContext));2480 for (uint32_t i = 0; i < cRects; ++i)2481 {2482 LogFunc(("rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));2483 }2484 2485 rc = vmsvga3dContextFromCid(pState, pSurface->idAssociatedContext, &pContext);2486 AssertRCReturn(rc, rc);2487 2488 hr = pContext->pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);2489 AssertMsgReturn(hr == D3D_OK, ("GetBackBuffer failed with %x\n", hr), VERR_INTERNAL_ERROR);2490 2491 rc = vmsvga3dGetD3DSurface(pState, pContext, pSurface, 0, 0, false, &pSurfaceD3D);2492 AssertRCReturn(rc, rc);2493 2494 /* Read the destination viewport specs in one go to try avoid some unnecessary update races. */2495 VMSVGAVIEWPORT const DstViewport = pThis->svga.viewport;2496 ASMCompilerBarrier(); /* paranoia */2497 Assert(DstViewport.yHighWC >= DstViewport.yLowWC);2498 2499 /* If there are no recangles specified, just grab a screenful. */2500 SVGA3dCopyRect DummyRect;2501 if (cRects != 0)2502 { /* likely */ }2503 else2504 {2505 /** @todo Find the usecase for this or check what the original device does.2506 * The original code was doing some scaling based on the surface2507 * size... */2508 # ifdef DEBUG_bird2509 AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n"));2510 # endif2511 DummyRect.x = DummyRect.srcx = 0;2512 DummyRect.y = DummyRect.srcy = 0;2513 DummyRect.w = pThis->svga.uWidth;2514 DummyRect.h = pThis->svga.uHeight;2515 cRects = 1;2516 pRect = &DummyRect;2517 }2518 2519 /*2520 * Blit the surface rectangle(s) to the back buffer.2521 */2522 Assert(pSurface->cxBlock == 1 && pSurface->cyBlock == 1);2523 uint32_t const cxSurface = pSurface->pMipmapLevels[0].mipmapSize.width;2524 uint32_t const cySurface = pSurface->pMipmapLevels[0].mipmapSize.height;2525 for (uint32_t i = 0; i < cRects; i++)2526 {2527 SVGA3dCopyRect ClippedRect = pRect[i];2528 2529 /*2530 * Do some sanity checking and limit width and height, all so we2531 * don't need to think about wrap-arounds below.2532 */2533 if (RT_LIKELY( ClippedRect.w2534 && ClippedRect.x < VMSVGA_MAX_X2535 && ClippedRect.srcx < VMSVGA_MAX_X2536 && ClippedRect.h2537 && ClippedRect.y < VMSVGA_MAX_Y2538 && ClippedRect.srcy < VMSVGA_MAX_Y2539 ))2540 { /* likely */ }2541 else2542 continue;2543 2544 if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))2545 { /* likely */ }2546 else2547 ClippedRect.w = VMSVGA_MAX_Y;2548 if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))2549 { /* likely */ }2550 else2551 ClippedRect.w = VMSVGA_MAX_Y;2552 2553 /*2554 * Source surface clipping (paranoia). Straight forward.2555 */2556 if (RT_LIKELY(ClippedRect.srcx < cxSurface))2557 { /* likely */ }2558 else2559 continue;2560 if (RT_LIKELY(ClippedRect.srcx + ClippedRect.w <= cxSurface))2561 { /* likely */ }2562 else2563 {2564 AssertFailed(); /* remove if annoying. */2565 ClippedRect.w = cxSurface - ClippedRect.srcx;2566 }2567 2568 if (RT_LIKELY(ClippedRect.srcy < cySurface))2569 { /* likely */ }2570 else2571 continue;2572 if (RT_LIKELY(ClippedRect.srcy + ClippedRect.h <= cySurface))2573 { /* likely */ }2574 else2575 {2576 AssertFailed(); /* remove if annoying. */2577 ClippedRect.h = cySurface - ClippedRect.srcy;2578 }2579 2580 /*2581 * Destination viewport clipping.2582 *2583 * This is very straight forward compared to OpenGL. There is no Y2584 * inversion anywhere and all the coordinate systems are the same.2585 */2586 /* X */2587 if (ClippedRect.x >= DstViewport.x)2588 {2589 if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)2590 { /* typical */ }2591 else if (ClippedRect.x < DstViewport.xRight)2592 ClippedRect.w = DstViewport.xRight - ClippedRect.x;2593 else2594 continue;2595 }2596 else2597 {2598 uint32_t cxAdjust = DstViewport.x - ClippedRect.x;2599 if (cxAdjust < ClippedRect.w)2600 {2601 ClippedRect.w -= cxAdjust;2602 ClippedRect.x += cxAdjust;2603 ClippedRect.srcx += cxAdjust;2604 }2605 else2606 continue;2607 2608 if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)2609 { /* typical */ }2610 else2611 ClippedRect.w = DstViewport.xRight - ClippedRect.x;2612 }2613 2614 /* Y */2615 if (ClippedRect.y >= DstViewport.y)2616 {2617 if (ClippedRect.y + ClippedRect.h <= DstViewport.y + DstViewport.cy)2618 { /* typical */ }2619 else if (ClippedRect.x < DstViewport.y + DstViewport.cy)2620 ClippedRect.h = DstViewport.y + DstViewport.cy - ClippedRect.y;2621 else2622 continue;2623 }2624 else2625 {2626 uint32_t cyAdjust = DstViewport.y - ClippedRect.y;2627 if (cyAdjust < ClippedRect.h)2628 {2629 ClippedRect.h -= cyAdjust;2630 ClippedRect.y += cyAdjust;2631 ClippedRect.srcy += cyAdjust;2632 }2633 else2634 continue;2635 2636 if (ClippedRect.y + ClippedRect.h <= DstViewport.y + DstViewport.cy)2637 { /* typical */ }2638 else2639 ClippedRect.h = DstViewport.y + DstViewport.cy - ClippedRect.y;2640 }2641 2642 /* Calc source rectangle. */2643 RECT SrcRect;2644 SrcRect.left = ClippedRect.srcx;2645 SrcRect.right = ClippedRect.srcx + ClippedRect.w;2646 SrcRect.top = ClippedRect.srcy;2647 SrcRect.bottom = ClippedRect.srcy + ClippedRect.h;2648 2649 /* Calc destination rectangle. */2650 RECT DstRect;2651 DstRect.left = ClippedRect.x;2652 DstRect.right = ClippedRect.x + ClippedRect.w;2653 DstRect.top = ClippedRect.y;2654 DstRect.bottom = ClippedRect.y + ClippedRect.h;2655 2656 /* Adjust for viewport. */2657 DstRect.left -= DstViewport.x;2658 DstRect.right -= DstViewport.x;2659 DstRect.bottom -= DstViewport.y;2660 DstRect.top -= DstViewport.y;2661 2662 Log(("SrcRect: (%d,%d)(%d,%d) DstRect: (%d,%d)(%d,%d)\n",2663 SrcRect.left, SrcRect.bottom, SrcRect.right, SrcRect.top,2664 DstRect.left, DstRect.bottom, DstRect.right, DstRect.top));2665 hr = pContext->pDevice->StretchRect(pSurfaceD3D, &SrcRect, pBackBuffer, &DstRect, D3DTEXF_NONE);2666 AssertBreak(hr == D3D_OK);2667 }2668 2669 D3D_RELEASE(pSurfaceD3D);2670 D3D_RELEASE(pBackBuffer);2671 2672 AssertMsgReturn(hr == D3D_OK, ("StretchRect failed with %x\n", hr), VERR_INTERNAL_ERROR);2673 2674 hr = pContext->pDevice->Present(NULL, NULL, NULL, NULL);2675 AssertMsgReturn(hr == D3D_OK, ("Present failed with %x\n", hr), VERR_INTERNAL_ERROR);2676 2677 return VINF_SUCCESS;2678 }2679 2680 2462 2681 2463 /** … … 2729 2511 pContext->state.aRenderTargets[i] = SVGA3D_INVALID_ID; 2730 2512 2731 /* Create a context window. */ 2513 /* Create a context window with minimal 4x4 size. We will never use the swapchain 2514 * to present the rendered image. Rendered images from the guest will be copied to 2515 * the VMSVGA SCREEN object, which can be either an offscreen render target or 2516 * system memory in the guest VRAM. 2517 */ 2732 2518 CREATESTRUCT cs; 2733 2519 … … 2735 2521 2736 2522 cs.lpCreateParams = NULL; 2737 cs.dwExStyle = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT;2523 cs.dwExStyle = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY; 2738 2524 #ifdef DEBUG_GFX_WINDOW 2739 2525 cs.lpszName = (char *)RTMemAllocZ(256); … … 2746 2532 cs.style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_CAPTION; 2747 2533 #else 2748 cs.style = WS_ CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | WS_CHILD | WS_VISIBLE;2534 cs.style = WS_DISABLED | WS_CHILD; 2749 2535 #endif 2750 2536 cs.x = 0; 2751 2537 cs.y = 0; 2752 cs.cx = pThis->svga.uWidth;2753 cs.cy = pThis->svga.uHeight;2538 cs.cx = 4; 2539 cs.cy = 4; 2754 2540 cs.hwndParent = (HWND)pThis->svga.u64HostWindowId; 2755 2541 cs.hMenu = NULL; … … 2767 2553 PresParam.MultiSampleType = D3DMULTISAMPLE_NONE; 2768 2554 PresParam.MultiSampleQuality = 0; 2769 PresParam.SwapEffect = D3DSWAPEFFECT_ FLIP;2555 PresParam.SwapEffect = D3DSWAPEFFECT_DISCARD; 2770 2556 PresParam.hDeviceWindow = pContext->hwnd; 2771 2557 PresParam.Windowed = TRUE; /** @todo */ -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
r73297 r73736 886 886 return VINF_SUCCESS; 887 887 } 888 889 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect) 890 { 891 /* Deprecated according to svga3d_reg.h. */ 892 PVMSVGA3DSTATE pState = pThis->svga.p3dState; 893 AssertReturn(pState, VERR_NO_MEMORY); 894 895 PVMSVGA3DSURFACE pSurface; 896 int rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface); 897 AssertRCReturn(rc, rc); 898 899 /* If there are no recangles specified, just grab a screenful. */ 900 SVGA3dCopyRect DummyRect; 901 if (cRects != 0) 902 { /* likely */ } 903 else 904 { 905 /** @todo Find the usecase for this or check what the original device does. 906 * The original code was doing some scaling based on the surface 907 * size... */ 908 AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n")); 909 DummyRect.x = DummyRect.srcx = 0; 910 DummyRect.y = DummyRect.srcy = 0; 911 DummyRect.w = pThis->svga.uWidth; 912 DummyRect.h = pThis->svga.uHeight; 913 cRects = 1; 914 pRect = &DummyRect; 915 } 916 917 uint32_t i; 918 for (i = 0; i < cRects; ++i) 919 { 920 uint32_t idDstScreen = 0; /** @todo Use virtual coords: SVGA_ID_INVALID. */ 921 SVGASignedRect destRect; 922 destRect.left = pRect[i].x; 923 destRect.top = pRect[i].y; 924 destRect.right = pRect[i].x + pRect[i].w; 925 destRect.bottom = pRect[i].y + pRect[i].h; 926 927 SVGA3dSurfaceImageId src; 928 src.sid = sid; 929 src.face = 0; 930 src.mipmap = 0; 931 932 SVGASignedRect srcRect; 933 srcRect.left = pRect[i].srcx; 934 srcRect.top = pRect[i].srcy; 935 srcRect.right = pRect[i].srcx + pRect[i].w; 936 srcRect.bottom = pRect[i].srcy + pRect[i].h; 937 938 /* Entire rect. */ 939 uint32_t cRects = 0; 940 SVGASignedRect *pRect = NULL; 941 942 rc = vmsvga3dSurfaceBlitToScreen(pThis, idDstScreen, destRect, src, srcRect, cRects, pRect); 943 AssertRCReturn(rc, rc); 944 } 945 946 return VINF_SUCCESS; 947 }
Note:
See TracChangeset
for help on using the changeset viewer.