• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Display.cpp: Implements the Display class, representing the abstract
16 // display on which graphics are drawn.
17 
18 #include "Display.h"
19 
20 #include "main.h"
21 #include "mathutil.h"
22 #include "Device.hpp"
23 #include "common/debug.h"
24 
25 #include <algorithm>
26 #include <vector>
27 #include <map>
28 
29 namespace gl
30 {
31 typedef std::map<NativeDisplayType, Display*> DisplayMap;
32 DisplayMap displays;
33 
getDisplay(NativeDisplayType displayId)34 Display *Display::getDisplay(NativeDisplayType displayId)
35 {
36 	if(displays.find(displayId) != displays.end())
37 	{
38 		return displays[displayId];
39 	}
40 
41 	// FIXME: Check if displayId is a valid display device context
42 	Display *display = new Display(displayId);
43 
44 	displays[displayId] = display;
45 	return display;
46 }
47 
Display(NativeDisplayType displayId)48 Display::Display(NativeDisplayType displayId) : displayId(displayId)
49 {
50 	mMinSwapInterval = 1;
51 	mMaxSwapInterval = 0;
52 }
53 
~Display()54 Display::~Display()
55 {
56 	terminate();
57 
58 	displays.erase(displayId);
59 }
60 
cpuid(int registers[4],int info)61 static void cpuid(int registers[4], int info)
62 {
63 	#if defined(_WIN32)
64 		__cpuid(registers, info);
65 	#else
66 		__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
67 	#endif
68 }
69 
detectSSE()70 static bool detectSSE()
71 {
72 	#if defined(__APPLE__)
73 		int SSE = false;
74 		size_t length = sizeof(SSE);
75 		sysctlbyname("hw.optional.sse", &SSE, &length, 0, 0);
76 		return SSE;
77 	#else
78 		int registers[4];
79 		cpuid(registers, 1);
80 		return (registers[3] & 0x02000000) != 0;
81 	#endif
82 }
83 
initialize()84 bool Display::initialize()
85 {
86 	if(isInitialized())
87 	{
88 		return true;
89 	}
90 
91 	if(!detectSSE())
92 	{
93 		 return false;
94 	}
95 
96 	mMinSwapInterval = 0;
97 	mMaxSwapInterval = 4;
98 
99 	if(!isInitialized())
100 	{
101 		terminate();
102 
103 		return false;
104 	}
105 
106 	return true;
107 }
108 
terminate()109 void Display::terminate()
110 {
111 	while(!mSurfaceSet.empty())
112 	{
113 		destroySurface(*mSurfaceSet.begin());
114 	}
115 
116 	while(!mContextSet.empty())
117 	{
118 		destroyContext(*mContextSet.begin());
119 	}
120 }
121 
createContext(const gl::Context * shareContext)122 gl::Context *Display::createContext(const gl::Context *shareContext)
123 {
124 	gl::Context *context = new gl::Context(shareContext);
125 	mContextSet.insert(context);
126 
127 	return context;
128 }
129 
destroySurface(Surface * surface)130 void Display::destroySurface(Surface *surface)
131 {
132 	delete surface;
133 	mSurfaceSet.erase(surface);
134 }
135 
destroyContext(gl::Context * context)136 void Display::destroyContext(gl::Context *context)
137 {
138 	delete context;
139 
140 	if(context == gl::getContext())
141 	{
142 		gl::makeCurrent(nullptr, nullptr, nullptr);
143 	}
144 
145 	mContextSet.erase(context);
146 }
147 
isInitialized() const148 bool Display::isInitialized() const
149 {
150 	return mMinSwapInterval <= mMaxSwapInterval;
151 }
152 
isValidContext(gl::Context * context)153 bool Display::isValidContext(gl::Context *context)
154 {
155 	return mContextSet.find(context) != mContextSet.end();
156 }
157 
isValidSurface(Surface * surface)158 bool Display::isValidSurface(Surface *surface)
159 {
160 	return mSurfaceSet.find(surface) != mSurfaceSet.end();
161 }
162 
isValidWindow(NativeWindowType window)163 bool Display::isValidWindow(NativeWindowType window)
164 {
165 	#if defined(_WIN32)
166 		return IsWindow(window) == TRUE;
167 	#else
168 		XWindowAttributes windowAttributes;
169 		Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
170 
171 		return status == True;
172 	#endif
173 }
174 
getMinSwapInterval()175 GLint Display::getMinSwapInterval()
176 {
177 	return mMinSwapInterval;
178 }
179 
getMaxSwapInterval()180 GLint Display::getMaxSwapInterval()
181 {
182 	return mMaxSwapInterval;
183 }
184 
getPrimarySurface()185 Surface *Display::getPrimarySurface()
186 {
187 	if(mSurfaceSet.size() == 0)
188 	{
189 		Surface *surface = new Surface(this, WindowFromDC(displayId));
190 
191 		if(!surface->initialize())
192 		{
193 			delete surface;
194 			return 0;
195 		}
196 
197 		mSurfaceSet.insert(surface);
198 
199 		gl::setCurrentDrawSurface(surface);
200 	}
201 
202 	return *mSurfaceSet.begin();
203 }
204 
getNativeDisplay() const205 NativeDisplayType Display::getNativeDisplay() const
206 {
207 	return displayId;
208 }
209 
getDisplayMode() const210 DisplayMode Display::getDisplayMode() const
211 {
212 	DisplayMode displayMode = {0};
213 
214 	#if defined(_WIN32)
215 		HDC deviceContext = GetDC(0);
216 
217 		displayMode.width = ::GetDeviceCaps(deviceContext, HORZRES);
218 		displayMode.height = ::GetDeviceCaps(deviceContext, VERTRES);
219 		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
220 
221 		switch(bpp)
222 		{
223 		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
224 		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
225 		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
226 		default:
227 			ASSERT(false);   // Unexpected display mode color depth
228 		}
229 
230 		ReleaseDC(0, deviceContext);
231 	#else
232 		Screen *screen = XDefaultScreenOfDisplay(displayId);
233 		displayMode.width = XWidthOfScreen(screen);
234 		displayMode.height = XHeightOfScreen(screen);
235 		unsigned int bpp = XPlanesOfScreen(screen);
236 
237 		switch(bpp)
238 		{
239 		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
240 		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
241 		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
242 		default:
243 			ASSERT(false);   // Unexpected display mode color depth
244 		}
245 	#endif
246 
247 	return displayMode;
248 }
249 
250 }
251