aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/psp/display_manager.h
blob: 5176bee3fe2e678a6769d652474b81eeea84b90b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef PSP_DISPLAY_MAN_H
#define PSP_DISPLAY_MAN_H

#include "backends/platform/psp/thread.h"
#include "common/list.h"

#define UNCACHED(x)		((byte *)(((uint32)(x)) | 0x40000000))	/* make an uncached access */
#define CACHED(x)		((byte *)(((uint32)(x)) & 0xBFFFFFFF))	/* make an uncached access into a cached one */

/**
 *	Class that allocates memory in the VRAM
 */
class VramAllocator : public Common::Singleton<VramAllocator> {
public:
	VramAllocator() : _bytesAllocated(0) {}
	void *allocate(int32 size, bool smallAllocation = false);	// smallAllocation e.g. palettes
	void deallocate(void *pointer);

	static inline bool isAddressInVram(void *address) {
		if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
			return true;
		return false;
	}


private:
	/**
	 *	Used to allocate in VRAM
	 */
	struct Allocation {
		byte *address;
		uint32 size;
		void *getEnd() { return address + size; }
		Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
		Allocation() : address(0), size(0) {}
	};

	enum {
		VRAM_START_ADDRESS = 0x04000000,
		VRAM_END_ADDRESS   = 0x04200000,
		VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4 * 1024)	// 4K in the end for small allocations
	};
	Common::List <Allocation> _allocList;		// List of allocations
	uint32 _bytesAllocated;
};


/**
 *	Class used only by DisplayManager to start/stop GU rendering
 */
class MasterGuRenderer : public PspThreadable {
public:
	MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), 
		_renderSema(1, 1), _callbackId(-1) {}
	void guInit();
	void guPreRender();
	void guPostRender();
	void guShutDown();
	bool isRenderFinished() { return _renderFinished; }
	void sleepUntilRenderFinished();
	void setupCallbackThread();
private:
	virtual void threadFunction();			// for the display callback thread
	static uint32 _displayList[];
	uint32 _lastRenderTime;					// For measuring rendering time
	void guProgramDisplayBufferSizes();
	static int guCallback(int, int, void *__this);	// for the display callback
	bool _renderFinished;					// for sync with render callback
	PspSemaphore _renderSema;				// semaphore for syncing
	int _callbackId;						// to keep track of render callback
};

class Screen;
class Overlay;
class Cursor;
class PSPKeyboard;
class ImageViewer;

/**
 *	Class that manages all display clients
 */
class DisplayManager {
public:
	enum GraphicsModeID {			///> Possible output formats onscreen
		ORIGINAL_RESOLUTION,
		KEEP_ASPECT_RATIO,
		STRETCHED_FULL_SCREEN
	};
	DisplayManager() : _screen(0), _cursor(0), _overlay(0), _keyboard(0), 
					  _imageViewer(0), _lastUpdateTime(0), _graphicsMode(0) {}
	~DisplayManager();

	void init();
	bool renderAll();	// return true if rendered or nothing dirty. False otherwise
	void waitUntilRenderFinished();
	bool setGraphicsMode(int mode);
	bool setGraphicsMode(const char *name);
	int getGraphicsMode() const { return _graphicsMode; }
	uint32 getDefaultGraphicsMode() const { return STRETCHED_FULL_SCREEN; }
	const OSystem::GraphicsMode* getSupportedGraphicsModes() const { return _supportedModes; }

	// Setters for pointers
	void setScreen(Screen *screen) { _screen = screen; }
	void setCursor(Cursor *cursor) { _cursor = cursor; }
	void setOverlay(Overlay *overlay) { _overlay = overlay; }
	void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
	void setImageViewer(ImageViewer *imageViewer) { _imageViewer = imageViewer; }
	
	void setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format);

	// Getters
	float getScaleX() const { return _displayParams.scaleX; }
	float getScaleY() const { return _displayParams.scaleY; }
	uint32 getOutputWidth() const { return _displayParams.screenOutput.width; }
	uint32 getOutputHeight() const { return _displayParams.screenOutput.height; }
	uint32 getOutputBitsPerPixel() const { return _displayParams.outputBitsPerPixel; }
	Common::List<Graphics::PixelFormat> getSupportedPixelFormats() const;

private:
	struct GlobalDisplayParams {
		Dimensions screenOutput;
		Dimensions screenSource;
		float scaleX;
		float scaleY;
		uint32 outputBitsPerPixel;		// How many bits end up on-screen
		GlobalDisplayParams() : scaleX(0.0f), scaleY(0.0f), outputBitsPerPixel(0) {}
	};

	// Pointers to DisplayClients
	Screen *_screen;
	Cursor *_cursor;
	Overlay *_overlay;
	PSPKeyboard *_keyboard;
	ImageViewer *_imageViewer;

	MasterGuRenderer _masterGuRenderer;
	uint32 _lastUpdateTime;					// For limiting FPS
	int _graphicsMode;
	GlobalDisplayParams _displayParams;
	static const OSystem::GraphicsMode _supportedModes[];

	void calculateScaleParams();	// calculates scaling factor
	bool isTimeToUpdate();			// should we update the screen now
};


#endif /* PSP_DISPLAY_MAN_H */