blob: 90a469e66036685924d271bdbad24578f9d70c43 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "FrameBufferGDI.hpp"
16
Nicolas Capens708c24b2017-10-26 13:07:10 -040017#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040018
19namespace sw
20{
21 extern bool forceWindowed;
22
John Bauman66b8ab22014-05-06 15:57:45 -040023 FrameBufferGDI::FrameBufferGDI(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin) : FrameBufferWin(windowHandle, width, height, fullscreen, topLeftOrigin)
John Bauman89401822014-05-06 15:04:28 -040024 {
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;
Nicolas Capens0bac2852016-05-07 06:09:58 -040033 deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
John Bauman89401822014-05-06 15:04:28 -040034
35 ChangeDisplaySettings(&deviceMode, CDS_FULLSCREEN);
36 }
37
38 init(this->windowHandle);
39
Nicolas Capense5a96372017-08-11 15:14:25 -040040 format = FORMAT_X8R8G8B8;
John Bauman89401822014-05-06 15:04:28 -040041 }
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
Nicolas Capense5a96372017-08-11 15:14:25 -040067 return framebuffer;
John Bauman89401822014-05-06 15:04:28 -040068 }
69
70 void FrameBufferGDI::unlock()
71 {
72 }
73
Nicolas Capens241f7892015-12-30 23:40:45 -050074 void FrameBufferGDI::flip(sw::Surface *source)
John Bauman66b8ab22014-05-06 15:57:45 -040075 {
Nicolas Capens241f7892015-12-30 23:40:45 -050076 blit(source, nullptr, nullptr);
John Bauman66b8ab22014-05-06 15:57:45 -040077 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040078
Nicolas Capens241f7892015-12-30 23:40:45 -050079 void FrameBufferGDI::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
John Bauman66b8ab22014-05-06 15:57:45 -040080 {
Nicolas Capens241f7892015-12-30 23:40:45 -050081 copy(source);
John Bauman66b8ab22014-05-06 15:57:45 -040082
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
Nicolas Capens241f7892015-12-30 23:40:45 -050095 void FrameBufferGDI::flip(HWND windowOverride, sw::Surface *source)
John Bauman89401822014-05-06 15:04:28 -040096 {
Nicolas Capens241f7892015-12-30 23:40:45 -050097 blit(windowOverride, source, nullptr, nullptr);
John Bauman89401822014-05-06 15:04:28 -040098 }
99
Nicolas Capens241f7892015-12-30 23:40:45 -0500100 void FrameBufferGDI::blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
John Bauman89401822014-05-06 15:04:28 -0400101 {
102 if(windowed && windowOverride != 0 && windowOverride != bitmapWindow)
103 {
104 release();
105 init(windowOverride);
106 }
107
Nicolas Capens241f7892015-12-30 23:40:45 -0500108 blit(source, sourceRect, destRect);
John Bauman89401822014-05-06 15:04:28 -0400109 }
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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400148
Nicolas Capense5a96372017-08-11 15:14:25 -0400149 bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &framebuffer, 0, 0);
John Bauman89401822014-05-06 15:04:28 -0400150 SelectObject(bitmapContext, bitmap);
John Bauman66b8ab22014-05-06 15:57:45 -0400151
152 updateBounds(window);
John Bauman89401822014-05-06 15:04:28 -0400153 }
154
155 void FrameBufferGDI::release()
156 {
157 SelectObject(bitmapContext, 0);
158 DeleteObject(bitmap);
John Bauman19bac1e2014-05-06 15:23:49 -0400159 ReleaseDC(bitmapWindow, windowContext);
John Bauman89401822014-05-06 15:04:28 -0400160 DeleteDC(bitmapContext);
161 }
162}