1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "FrameBufferGDI.hpp" 16 17 #include "Common/Debug.hpp" 18 19 namespace sw 20 { 21 extern bool forceWindowed; 22 FrameBufferGDI(HWND windowHandle,int width,int height,bool fullscreen,bool topLeftOrigin)23 FrameBufferGDI::FrameBufferGDI(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin) : FrameBufferWin(windowHandle, width, height, fullscreen, topLeftOrigin) 24 { 25 if(!windowed) 26 { 27 SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, width, height, SWP_SHOWWINDOW); 28 29 DEVMODE deviceMode; 30 deviceMode.dmSize = sizeof(DEVMODE); 31 deviceMode.dmPelsWidth= width; 32 deviceMode.dmPelsHeight = height; 33 deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; 34 35 ChangeDisplaySettings(&deviceMode, CDS_FULLSCREEN); 36 } 37 38 init(this->windowHandle); 39 40 format = FORMAT_X8R8G8B8; 41 } 42 ~FrameBufferGDI()43 FrameBufferGDI::~FrameBufferGDI() 44 { 45 release(); 46 47 if(!windowed) 48 { 49 ChangeDisplaySettings(0, 0); 50 51 RECT clientRect; 52 RECT windowRect; 53 GetClientRect(windowHandle, &clientRect); 54 GetWindowRect(windowHandle, &windowRect); 55 int windowWidth = width + (windowRect.right - windowRect.left) - (clientRect.right - clientRect.left); 56 int windowHeight = height + (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top); 57 int desktopWidth = GetSystemMetrics(SM_CXSCREEN); 58 int desktopHeight = GetSystemMetrics(SM_CYSCREEN); 59 SetWindowPos(windowHandle, HWND_TOP, desktopWidth / 2 - windowWidth / 2, desktopHeight / 2 - windowHeight / 2, windowWidth, windowHeight, SWP_SHOWWINDOW); 60 } 61 } 62 lock()63 void *FrameBufferGDI::lock() 64 { 65 stride = width * 4; 66 67 return framebuffer; 68 } 69 unlock()70 void FrameBufferGDI::unlock() 71 { 72 } 73 flip(sw::Surface * source)74 void FrameBufferGDI::flip(sw::Surface *source) 75 { 76 blit(source, nullptr, nullptr); 77 } 78 blit(sw::Surface * source,const Rect * sourceRect,const Rect * destRect)79 void FrameBufferGDI::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) 80 { 81 copy(source); 82 83 int sourceLeft = sourceRect ? sourceRect->x0 : 0; 84 int sourceTop = sourceRect ? sourceRect->y0 : 0; 85 int sourceWidth = sourceRect ? sourceRect->x1 - sourceRect->x0 : width; 86 int sourceHeight = sourceRect ? sourceRect->y1 - sourceRect->y0 : height; 87 int destLeft = destRect ? destRect->x0 : 0; 88 int destTop = destRect ? destRect->y0 : 0; 89 int destWidth = destRect ? destRect->x1 - destRect->x0 : bounds.right - bounds.left; 90 int destHeight = destRect ? destRect->y1 - destRect->y0 : bounds.bottom - bounds.top; 91 92 StretchBlt(windowContext, destLeft, destTop, destWidth, destHeight, bitmapContext, sourceLeft, sourceTop, sourceWidth, sourceHeight, SRCCOPY); 93 } 94 flip(HWND windowOverride,sw::Surface * source)95 void FrameBufferGDI::flip(HWND windowOverride, sw::Surface *source) 96 { 97 blit(windowOverride, source, nullptr, nullptr); 98 } 99 blit(HWND windowOverride,sw::Surface * source,const Rect * sourceRect,const Rect * destRect)100 void FrameBufferGDI::blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect) 101 { 102 if(windowed && windowOverride != 0 && windowOverride != bitmapWindow) 103 { 104 release(); 105 init(windowOverride); 106 } 107 108 blit(source, sourceRect, destRect); 109 } 110 setGammaRamp(GammaRamp * gammaRamp,bool calibrate)111 void FrameBufferGDI::setGammaRamp(GammaRamp *gammaRamp, bool calibrate) 112 { 113 SetDeviceGammaRamp(windowContext, gammaRamp); 114 } 115 getGammaRamp(GammaRamp * gammaRamp)116 void FrameBufferGDI::getGammaRamp(GammaRamp *gammaRamp) 117 { 118 GetDeviceGammaRamp(windowContext, gammaRamp); 119 } 120 screenshot(void * destBuffer)121 void FrameBufferGDI::screenshot(void *destBuffer) 122 { 123 UNIMPLEMENTED(); 124 } 125 getScanline(bool & inVerticalBlank,unsigned int & scanline)126 bool FrameBufferGDI::getScanline(bool &inVerticalBlank, unsigned int &scanline) 127 { 128 UNIMPLEMENTED(); 129 130 return false; 131 } 132 init(HWND window)133 void FrameBufferGDI::init(HWND window) 134 { 135 bitmapWindow = window; 136 137 windowContext = GetDC(window); 138 bitmapContext = CreateCompatibleDC(windowContext); 139 140 BITMAPINFO bitmapInfo; 141 memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); 142 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO); 143 bitmapInfo.bmiHeader.biBitCount = 32; 144 bitmapInfo.bmiHeader.biPlanes = 1; 145 bitmapInfo.bmiHeader.biHeight = -height; 146 bitmapInfo.bmiHeader.biWidth = width; 147 bitmapInfo.bmiHeader.biCompression = BI_RGB; 148 149 bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &framebuffer, 0, 0); 150 SelectObject(bitmapContext, bitmap); 151 152 updateBounds(window); 153 } 154 release()155 void FrameBufferGDI::release() 156 { 157 SelectObject(bitmapContext, 0); 158 DeleteObject(bitmap); 159 ReleaseDC(bitmapWindow, windowContext); 160 DeleteDC(bitmapContext); 161 } 162 } 163