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 "Debug.hpp" 18 19namespace sw 20{ 21 extern bool forceWindowed; 22 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 destFormat = FORMAT_X8R8G8B8; 41 } 42 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 63 void *FrameBufferGDI::lock() 64 { 65 stride = width * 4; 66 67 return locked; 68 } 69 70 void FrameBufferGDI::unlock() 71 { 72 } 73 74 void FrameBufferGDI::flip(void *source, Format sourceFormat, size_t sourceStride) 75 { 76 blit(source, 0, 0, sourceFormat, sourceStride); 77 } 78 79 void FrameBufferGDI::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) 80 { 81 copy(source, sourceFormat, sourceStride); 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 95 void FrameBufferGDI::flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) 96 { 97 blit(windowOverride, source, 0, 0, sourceFormat, sourceStride); 98 } 99 100 void FrameBufferGDI::blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) 101 { 102 if(windowed && windowOverride != 0 && windowOverride != bitmapWindow) 103 { 104 release(); 105 init(windowOverride); 106 } 107 108 blit(source, sourceRect, destRect, sourceFormat, sourceStride); 109 } 110 111 void FrameBufferGDI::setGammaRamp(GammaRamp *gammaRamp, bool calibrate) 112 { 113 SetDeviceGammaRamp(windowContext, gammaRamp); 114 } 115 116 void FrameBufferGDI::getGammaRamp(GammaRamp *gammaRamp) 117 { 118 GetDeviceGammaRamp(windowContext, gammaRamp); 119 } 120 121 void FrameBufferGDI::screenshot(void *destBuffer) 122 { 123 UNIMPLEMENTED(); 124 } 125 126 bool FrameBufferGDI::getScanline(bool &inVerticalBlank, unsigned int &scanline) 127 { 128 UNIMPLEMENTED(); 129 130 return false; 131 } 132 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, &locked, 0, 0); 150 SelectObject(bitmapContext, bitmap); 151 152 updateBounds(window); 153 } 154 155 void FrameBufferGDI::release() 156 { 157 SelectObject(bitmapContext, 0); 158 DeleteObject(bitmap); 159 ReleaseDC(bitmapWindow, windowContext); 160 DeleteDC(bitmapContext); 161 } 162} 163