Changeset - r24908:4dfe7bc46264
[Not reviewed]
master
0 6 0
Michael Lutz - 3 years ago 2021-01-16 15:43:42
michi@icosahedron.de
Add: [OpenGL] Support for a separate animation buffer that stores the palette values of the screen in addition to the colour buffer.
6 files changed with 122 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/blitter/base.hpp
Show inline comments
 
@@ -177,24 +177,32 @@ public:
 
	 *  are equal to the 8bpp palette indexes 'first_dirty' to 'first_dirty + count_dirty'.
 
	 * @param palette The new palette.
 
	 */
 
	virtual void PaletteAnimate(const Palette &palette) = 0;
 

	
 
	/**
 
	 * Check if the blitter uses palette animation at all.
 
	 * @return True if it uses palette animation.
 
	 */
 
	virtual Blitter::PaletteAnimation UsePaletteAnimation() = 0;
 

	
 
	/**
 
	 * Does this blitter require a separate animation buffer from the video backend?
 
	 */
 
	virtual bool NeedsAnimationBuffer()
 
	{
 
		return false;
 
	}
 

	
 
	/**
 
	 * Get the name of the blitter, the same as the Factory-instance returns.
 
	 */
 
	virtual const char *GetName() = 0;
 

	
 
	/**
 
	 * Get how many bytes are needed to store a pixel.
 
	 */
 
	virtual int GetBytesPerPixel() = 0;
 

	
 
	/**
 
	 * Post resize event
 
	 */
src/video/opengl.cpp
Show inline comments
 
@@ -383,26 +383,28 @@ OpenGLBackend::~OpenGLBackend()
 
	ClearCursorCache();
 
	OpenGLSprite::Destroy();
 

	
 
	if (_glDeleteProgram != nullptr) {
 
		_glDeleteProgram(this->remap_program);
 
		_glDeleteProgram(this->vid_program);
 
		_glDeleteProgram(this->pal_program);
 
	}
 
	if (_glDeleteVertexArrays != nullptr) _glDeleteVertexArrays(1, &this->vao_quad);
 
	if (_glDeleteBuffers != nullptr) {
 
		_glDeleteBuffers(1, &this->vbo_quad);
 
		_glDeleteBuffers(1, &this->vid_pbo);
 
		_glDeleteBuffers(1, &this->anim_pbo);
 
	}
 
	glDeleteTextures(1, &this->vid_texture);
 
	glDeleteTextures(1, &this->anim_texture);
 
	glDeleteTextures(1, &this->pal_texture);
 
}
 

	
 
/**
 
 * Check for the needed OpenGL functionality and allocate all resources.
 
 * @return Error string or nullptr if successful.
 
 */
 
const char *OpenGLBackend::Init()
 
{
 
	/* Always query the supported OpenGL version as the current context might have changed. */
 
	const char *ver = (const char *)glGetString(GL_VERSION);
 
	const char *vend = (const char *)glGetString(GL_VENDOR);
 
@@ -449,24 +451,35 @@ const char *OpenGLBackend::Init()
 

	
 
	/* Setup video buffer texture. */
 
	glGenTextures(1, &this->vid_texture);
 
	glBindTexture(GL_TEXTURE_2D, this->vid_texture);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
	glBindTexture(GL_TEXTURE_2D, 0);
 
	if (glGetError() != GL_NO_ERROR) return "Can't generate video buffer texture";
 

	
 
	/* Setup video buffer texture. */
 
	glGenTextures(1, &this->anim_texture);
 
	glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
	glBindTexture(GL_TEXTURE_2D, 0);
 
	if (glGetError() != GL_NO_ERROR) return "Can't generate animation buffer texture";
 

	
 
	/* Setup palette texture. */
 
	glGenTextures(1, &this->pal_texture);
 
	glBindTexture(GL_TEXTURE_1D, this->pal_texture);
 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);
 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
 
	glBindTexture(GL_TEXTURE_1D, 0);
 
	if (glGetError() != GL_NO_ERROR) return "Can't generate palette lookup texture";
 

	
 
@@ -496,28 +509,31 @@ const char *OpenGLBackend::Init()
 
	/* Bind uniforms in remap shader program. */
 
	tex_location = _glGetUniformLocation(this->remap_program, "colour_tex");
 
	palette_location = _glGetUniformLocation(this->remap_program, "palette");
 
	GLint remap_location = _glGetUniformLocation(this->remap_program, "remap_tex");
 
	this->remap_sprite_loc = _glGetUniformLocation(this->remap_program, "sprite");
 
	this->remap_screen_loc = _glGetUniformLocation(this->remap_program, "screen");
 
	this->remap_zoom_loc = _glGetUniformLocation(this->remap_program, "zoom");
 
	this->remap_rgb_loc = _glGetUniformLocation(this->remap_program, "rgb");
 
	_glUseProgram(this->remap_program);
 
	_glUniform1i(tex_location, 0);     // Texture unit 0.
 
	_glUniform1i(palette_location, 1); // Texture unit 1.
 
	_glUniform1i(remap_location, 2);   // Texture unit 2.
 
	(void)glGetError(); // Clear errors.
 

	
 
	/* Create pixel buffer object as video buffer storage. */
 
	_glGenBuffers(1, &this->vid_pbo);
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
	_glGenBuffers(1, &this->anim_pbo);
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
	if (glGetError() != GL_NO_ERROR) return "Can't allocate pixel buffer for video buffer";
 

	
 
	/* Prime vertex buffer with a full-screen quad and store
 
	 * the corresponding state in a vertex array object. */
 
	static const Simple2DVertex vert_array[] = {
 
		//  x     y    u    v
 
		{  1.f, -1.f, 1.f, 1.f },
 
		{  1.f,  1.f, 1.f, 0.f },
 
		{ -1.f, -1.f, 0.f, 1.f },
 
		{ -1.f,  1.f, 0.f, 0.f },
 
	};
 

	
 
@@ -677,25 +693,25 @@ bool OpenGLBackend::InitShaders()
 
/**
 
 * Change the size of the drawing window and allocate matching resources.
 
 * @param w New width of the window.
 
 * @param h New height of the window.
 
 * @param force Recreate resources even if size didn't change.
 
 * @param False if nothing had to be done, true otherwise.
 
 */
 
bool OpenGLBackend::Resize(int w, int h, bool force)
 
{
 
	if (!force && _screen.width == w && _screen.height == h) return false;
 

	
 
	int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 
	int pitch = bpp != 32 ? Align(w, 4) : w;
 
	int pitch = Align(w, 4);
 

	
 
	glViewport(0, 0, w, h);
 

	
 
	/* Re-allocate video buffer texture and backing store. */
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
	_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_DYNAMIC_READ); // Buffer content has to persist from frame to frame and is read back by the blitter, which means a READ usage hint.
 
	if (bpp == 32) {
 
		/* Initialize backing store alpha to opaque for 32bpp modes. */
 
		Colour black(0, 0, 0);
 
		uint32 *buf = (uint32 *)_glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
 
		for (int i = 0; i < pitch * h; i++) {
 
			*buf++ = black.data;
 
@@ -706,24 +722,41 @@ bool OpenGLBackend::Resize(int w, int h,
 

	
 
	_glActiveTexture(GL_TEXTURE0);
 
	glBindTexture(GL_TEXTURE_2D, this->vid_texture);
 
	switch (bpp) {
 
		case 8:
 
			glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
 
			break;
 

	
 
		default:
 
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
 
			break;
 
	}
 

	
 
	/* Does this blitter need a separate animation buffer? */
 
	if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
		_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h, NULL, GL_DYNAMIC_READ); // Buffer content has to persist from frame to frame and is read back by the blitter, which means a READ usage hint.
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 

	
 
		glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
 
	} else {
 
		/* Allocate dummy texture that always reads as 0 == no remap. */
 
		uint dummy = 0;
 
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 
		glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &dummy);
 
	}
 

	
 
	glBindTexture(GL_TEXTURE_2D, 0);
 

	
 
	/* Set new viewport. */
 
	_screen.height = h;
 
	_screen.width = w;
 
	_screen.pitch = pitch;
 
	_screen.dst_ptr = nullptr;
 

	
 
	/* Update screen size in remap shader program. */
 
	_glUseProgram(this->remap_program);
 
	_glUniform2f(this->remap_screen_loc, (float)_screen.width, (float)_screen.height);
 

	
 
@@ -752,25 +785,36 @@ void OpenGLBackend::UpdatePalette(const 
 
 */
 
void OpenGLBackend::Paint()
 
{
 
	glClear(GL_COLOR_BUFFER_BIT);
 

	
 
	glDisable(GL_BLEND);
 

	
 
	/* Blit video buffer to screen. */
 
	_glActiveTexture(GL_TEXTURE0);
 
	glBindTexture(GL_TEXTURE_2D, this->vid_texture);
 
	_glActiveTexture(GL_TEXTURE1);
 
	glBindTexture(GL_TEXTURE_1D, this->pal_texture);
 
	_glUseProgram(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 8 ? this->pal_program : this->vid_program);
 
	/* Is the blitter relying on a separate animation buffer? */
 
	if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
 
		_glActiveTexture(GL_TEXTURE2);
 
		glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
		_glUseProgram(this->remap_program);
 
		_glUniform4f(this->remap_sprite_loc, 0.0f, 0.0f, 1.0f, 1.0f);
 
		_glUniform2f(this->remap_screen_loc, 1.0f, 1.0f);
 
		_glUniform1f(this->remap_zoom_loc, 0);
 
		_glUniform1i(this->remap_rgb_loc, 1);
 
	} else {
 
		_glUseProgram(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 8 ? this->pal_program : this->vid_program);
 
	}
 
	_glBindVertexArray(this->vao_quad);
 
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 

	
 
	glEnable(GL_BLEND);
 
}
 

	
 
/**
 
 * Draw mouse cursor on screen.
 
 */
 
void OpenGLBackend::DrawMouseCursor()
 
{
 
	/* Draw cursor on screen */
 
@@ -806,24 +850,36 @@ void OpenGLBackend::ClearCursorCache()
 

	
 
/**
 
 * Get a pointer to the memory for the video driver to draw to.
 
 * @return Pointer to draw on.
 
 */
 
void *OpenGLBackend::GetVideoBuffer()
 
{
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
	return _glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
 
}
 

	
 
/**
 
 * Get a pointer to the memory for the separate animation buffer.
 
 * @return Pointer to draw on.
 
 */
 
uint8 *OpenGLBackend::GetAnimBuffer()
 
{
 
	if (this->anim_pbo == 0) return nullptr;
 

	
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
	return (uint8 *)_glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
 
}
 

	
 
/**
 
 * Update video buffer texture after the video buffer was filled.
 
 * @param update_rect Rectangle encompassing the dirty region of the video buffer.
 
 */
 
void OpenGLBackend::ReleaseVideoBuffer(const Rect &update_rect)
 
{
 
	assert(this->vid_pbo != 0);
 

	
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
	_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
 

	
 
	/* Update changed rect of the video buffer texture. */
 
	if (!IsEmptyRect(update_rect)) {
 
@@ -833,24 +889,44 @@ void OpenGLBackend::ReleaseVideoBuffer(c
 
		switch (BlitterFactory::GetCurrentBlitter()->GetScreenDepth()) {
 
			case 8:
 
				glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)(size_t)(update_rect.top * _screen.pitch + update_rect.left));
 
				break;
 

	
 
			default:
 
				glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (GLvoid *)(size_t)(update_rect.top * _screen.pitch * 4 + update_rect.left * 4));
 
				break;
 
		}
 
	}
 
}
 

	
 
/**
 
 * Update animation buffer texture after the animation buffer was filled.
 
 * @param update_rect Rectangle encompassing the dirty region of the animation buffer.
 
 */
 
void OpenGLBackend::ReleaseAnimBuffer(const Rect &update_rect)
 
{
 
	if (this->anim_pbo == 0) return;
 

	
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
	_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
 

	
 
	/* Update changed rect of the video buffer texture. */
 
	if (update_rect.left != update_rect.right) {
 
		_glActiveTexture(GL_TEXTURE0);
 
		glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
		glPixelStorei(GL_UNPACK_ROW_LENGTH, _screen.pitch);
 
		glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)(size_t)(update_rect.top * _screen.pitch + update_rect.left));
 
	}
 
}
 

	
 
/* virtual */ Sprite *OpenGLBackend::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
 
{
 
	/* Allocate and construct sprite data. */
 
	Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(OpenGLSprite));
 

	
 
	OpenGLSprite *gl_sprite = (OpenGLSprite *)dest_sprite->data;
 
	new (gl_sprite) OpenGLSprite(sprite->width, sprite->height, sprite->type == ST_FONT ? 1 : ZOOM_LVL_COUNT, sprite->colours);
 

	
 
	/* Upload texture data. */
 
	for (int i = 0; i < (sprite->type == ST_FONT ? 1 : ZOOM_LVL_COUNT); i++) {
 
		gl_sprite->Update(sprite[i].width, sprite[i].height, i, sprite[i].data);
 
	}
src/video/opengl.h
Show inline comments
 
@@ -30,24 +30,27 @@ class OpenGLSprite;
 
class OpenGLBackend : public ZeroedMemoryAllocator, SpriteEncoder {
 
private:
 
	static OpenGLBackend *instance; ///< Singleton instance pointer.
 

	
 
	GLuint vid_pbo;     ///< Pixel buffer object storing the memory used for the video driver to draw to.
 
	GLuint vid_texture; ///< Texture handle for the video buffer texture.
 
	GLuint vid_program; ///< Shader program for rendering a RGBA video buffer.
 
	GLuint pal_program; ///< Shader program for rendering a paletted video buffer.
 
	GLuint vao_quad;    ///< Vertex array object storing the rendering state for the fullscreen quad.
 
	GLuint vbo_quad;    ///< Vertex buffer with a fullscreen quad.
 
	GLuint pal_texture; ///< Palette lookup texture.
 

	
 
	GLuint anim_pbo;     ///< Pixel buffer object storing the memory used for the animation buffer.
 
	GLuint anim_texture; ///< Texture handle for the animation buffer texture.
 

	
 
	GLuint remap_program;    ///< Shader program for blending and rendering a RGBA + remap texture.
 
	GLint  remap_sprite_loc; ///< Uniform location for sprite parameters.
 
	GLint  remap_screen_loc; ///< Uniform location for screen size;
 
	GLint  remap_zoom_loc;   ///< Uniform location for sprite zoom;
 
	GLint  remap_rgb_loc;    ///< Uniform location for RGB mode flag;
 

	
 
	LRUCache<SpriteID, Sprite> cursor_cache; ///< Cache of encoded cursor sprites.
 

	
 
	OpenGLBackend();
 
	~OpenGLBackend();
 

	
 
	const char *Init();
 
@@ -63,25 +66,27 @@ public:
 
	}
 
	static const char *Create(GetOGLProcAddressProc get_proc);
 
	static void Destroy();
 

	
 
	void UpdatePalette(const Colour *pal, uint first, uint length);
 
	bool Resize(int w, int h, bool force = false);
 
	void Paint();
 

	
 
	void DrawMouseCursor();
 
	void ClearCursorCache();
 

	
 
	void *GetVideoBuffer();
 
	uint8 *GetAnimBuffer();
 
	void ReleaseVideoBuffer(const Rect &update_rect);
 
	void ReleaseAnimBuffer(const Rect &update_rect);
 

	
 
	/* SpriteEncoder */
 

	
 
	bool Is32BppSupported() override { return true; }
 
	uint GetSpriteAlignment() override { return 1u << (ZOOM_LVL_COUNT - 1); }
 
	Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
 
};
 

	
 

	
 
/** Class that encapsulates a RGBA texture together with a paletted remap texture. */
 
class OpenGLSprite {
 
private:
src/video/video_driver.hpp
Show inline comments
 
@@ -113,24 +113,42 @@ public:
 
	}
 

	
 
	/**
 
	 * Has this video driver an efficient code path for palette animated 8-bpp sprites?
 
	 * @return True if the driver has an efficient code path for 8-bpp.
 
	 */
 
	virtual bool HasEfficient8Bpp() const
 
	{
 
		return false;
 
	}
 

	
 
	/**
 
	 * Does this video driver support a separate animation buffer in addition to the colour buffer?
 
	 * @return True if a separate animation buffer is supported.
 
	 */
 
	virtual bool HasAnimBuffer()
 
	{
 
		return false;
 
	}
 

	
 
	/**
 
	 * Get a pointer to the animation buffer of the video back-end.
 
	 * @return Pointer to the buffer or nullptr if no animation buffer is supported.
 
	 */
 
	virtual uint8 *GetAnimBuffer()
 
	{
 
		return nullptr;
 
	}
 

	
 
	/**
 
	 * An edit box lost the input focus. Abort character compositing if necessary.
 
	 */
 
	virtual void EditBoxLostFocus() {}
 

	
 
	/**
 
	 * An edit box gained the input focus
 
	 */
 
	virtual void EditBoxGainedFocus() {}
 

	
 
	/**
 
	 * Get a suggested default GUI zoom taking screen DPI into account.
 
	 */
src/video/win32_v.cpp
Show inline comments
 
@@ -1536,32 +1536,37 @@ bool VideoDriver_Win32OpenGL::AllocateBa
 

	
 
	if (_screen.dst_ptr != nullptr) this->ReleaseVideoPointer();
 

	
 
	this->dirty_rect = {};
 
	bool res = OpenGLBackend::Get()->Resize(w, h, force);
 
	_screen.dst_ptr = this->GetVideoPointer();
 

	
 
	return res;
 
}
 

	
 
void *VideoDriver_Win32OpenGL::GetVideoPointer()
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
 
		this->anim_buffer = OpenGLBackend::Get()->GetAnimBuffer();
 
	}
 
	return OpenGLBackend::Get()->GetVideoBuffer();
 
}
 

	
 
void VideoDriver_Win32OpenGL::ReleaseVideoPointer()
 
{
 
	if (this->anim_buffer != nullptr) OpenGLBackend::Get()->ReleaseAnimBuffer(this->dirty_rect);
 
	OpenGLBackend::Get()->ReleaseVideoBuffer(this->dirty_rect);
 
	this->dirty_rect = {};
 
	_screen.dst_ptr = nullptr;
 
	this->anim_buffer = nullptr;
 
}
 

	
 
void VideoDriver_Win32OpenGL::Paint()
 
{
 
	PerformanceMeasurer framerate(PFE_VIDEO);
 

	
 
	if (_cur_palette.count_dirty != 0) {
 
		Blitter *blitter = BlitterFactory::GetCurrentBlitter();
 

	
 
		/* Always push a changed palette to OpenGL. */
 
		OpenGLBackend::Get()->UpdatePalette(_local_palette.palette, _local_palette.first_dirty, _local_palette.count_dirty);
 
		if (blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_BLITTER) {
src/video/win32_v.h
Show inline comments
 
@@ -119,46 +119,50 @@ public:
 
/** The factory for Windows' video driver. */
 
class FVideoDriver_Win32GDI : public DriverFactoryBase {
 
public:
 
	FVideoDriver_Win32GDI() : DriverFactoryBase(Driver::DT_VIDEO, 9, "win32", "Win32 GDI Video Driver") {}
 
	Driver *CreateInstance() const override { return new VideoDriver_Win32GDI(); }
 
};
 

	
 
#ifdef WITH_OPENGL
 

	
 
/** The OpenGL video driver for windows. */
 
class VideoDriver_Win32OpenGL : public VideoDriver_Win32Base {
 
public:
 
	VideoDriver_Win32OpenGL() : dc(nullptr), gl_rc(nullptr) {}
 
	VideoDriver_Win32OpenGL() : dc(nullptr), gl_rc(nullptr), anim_buffer(nullptr) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	bool AfterBlitterChange() override;
 

	
 
	bool HasEfficient8Bpp() const override { return true; }
 

	
 
	bool UseSystemCursor() override { return true; }
 

	
 
	void ClearSystemSprites() override;
 

	
 
	bool HasAnimBuffer() override { return true; }
 
	uint8 *GetAnimBuffer() override { return this->anim_buffer; }
 

	
 
	const char *GetName() const override { return "win32-opengl"; }
 

	
 
protected:
 
	HDC   dc;          ///< Window device context.
 
	HGLRC gl_rc;       ///< OpenGL context.
 
	bool  vsync;       ///< Enable VSync?
 
	HDC    dc;          ///< Window device context.
 
	HGLRC  gl_rc;       ///< OpenGL context.
 
	bool   vsync;       ///< Enable VSync?
 
	uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end.
 

	
 
	uint8 GetFullscreenBpp() override { return 32; } // OpenGL is always 32 bpp.
 

	
 
	void Paint() override;
 
	void PaintThread() override {}
 

	
 
	bool AllocateBackingStore(int w, int h, bool force = false) override;
 
	void *GetVideoPointer() override;
 
	void ReleaseVideoPointer() override;
 
	void PaletteChanged(HWND hWnd) override {}
 

	
 
	const char *AllocateContext();
0 comments (0 inline, 0 general)