Update to v106r55 release.

byuu says:

Everything *should* be working again, but of course that won't
actually be the case. Here's where things stand:

  - bsnes, higan, icarus, and genius compile and run fine on FreeBSD
    with GTK
  - ruby video and audio drivers are untested on Windows, macOS, and
    Linux
  - hiro is untested on macOS
  - bsnes' status bar is not showing up properly with hiro/qt
  - bsnes and higan's about screen is not showing up properly with
    hiro/qt (1x1 window size)
  - bsnes on Windows crashes often when saving states, and I'm not sure
    why ... it happens inside Encode::RLE
  - bsnes on Windows crashes with ruby.input.windows (unsure why)
  - bsnes on Windows fails to show the verified emblem on the status bar
    properly
  - hiro on Windows flickers when changing tabs

To build the Windows bsnes and higan ports, use

    ruby="video.gdi audio.directsound"

Compilation error logs for Linux will help me fix the inevitable list of
typos there. I can fix the typos on other platforms, I just haven't
gotten to it yet.
This commit is contained in:
Tim Allen
2018-08-05 19:00:15 +10:00
parent 552d385031
commit 5da4532771
117 changed files with 1316 additions and 2383 deletions

View File

@@ -11,10 +11,15 @@ struct VideoCGL;
-(void) reshape;
@end
struct VideoCGL : Video, OpenGL {
VideoCGL() { initialize(); }
struct VideoCGL : VideoDriver, OpenGL {
VideoCGL& self = *this;
VideoCGL(Video& super) : VideoDriver(super) {}
~VideoCGL() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "OpenGL"; }
auto ready() -> bool override { return _ready; }
@@ -25,14 +30,10 @@ struct VideoCGL : Video, OpenGL {
auto hasShader() -> bool override { return true; }
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
if(!view) return true;
@autoreleasepool {
[[view openGLContext] makeCurrentContext];
@@ -43,28 +44,21 @@ struct VideoCGL : Video, OpenGL {
}
auto setFlush(bool flush) -> bool override {
if(flush == Video::flush()) return true;
if(!Video::setFlush(flush)) return false;
return true;
}
auto setSmooth(bool smooth) -> bool override {
if(smooth == Video::smooth()) return true;
if(!Video::setSmooth(smooth)) return false;
if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST;
auto setSmooth(bool) -> bool override {
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto setShader(string shader) -> bool override {
if(shader == Video::shader()) return true;
if(!Video::setShader(shader)) return false;
OpenGL::setShader(shader);
if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST;
auto setShader(string) -> bool override {
OpenGL::setShader(self.shader);
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto clear() -> void override {
if(!ready()) return;
@autoreleasepool {
[view lockFocus];
OpenGL::clear();
@@ -74,17 +68,14 @@ struct VideoCGL : Video, OpenGL {
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
OpenGL::size(width, height);
return OpenGL::lock(data, pitch);
}
auto release() -> void override {
if(!ready()) return;
}
auto output() -> void override {
if(!ready()) return;
@autoreleasepool {
if([view lockFocusIfCanDraw]) {
auto area = [view convertRectToBacking:[view bounds]];
@@ -92,7 +83,7 @@ struct VideoCGL : Video, OpenGL {
OpenGL::outputHeight = area.size.height;
OpenGL::output();
[[view openGLContext] flushBuffer];
if(flush()) glFinish();
if(self.flush) glFinish();
[view unlockFocus];
}
}
@@ -101,7 +92,7 @@ struct VideoCGL : Video, OpenGL {
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
@autoreleasepool {
NSOpenGLPixelFormatAttribute attributeList[] = {
@@ -112,7 +103,7 @@ private:
0
};
auto context = (NSView*)_context;
auto context = (NSView*)self.context;
auto size = [context frame].size;
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
@@ -129,7 +120,7 @@ private:
OpenGL::initialize();
int blocking = _blocking;
int blocking = self.blocking;
[[view openGLContext] setValues:&blocking forParameter:NSOpenGLCPSwapInterval];
[view unlockFocus];

View File

@@ -7,10 +7,15 @@ static LRESULT CALLBACK VideoDirect3D_WindowProcedure(HWND hwnd, UINT msg, WPARA
return DefWindowProc(hwnd, msg, wparam, lparam);
}
struct VideoDirect3D : Video {
VideoDirect3D() { initialize(); }
struct VideoDirect3D : VideoDriver {
VideoDirect3D& self = *this;
VideoDirect3D(Video& super) : VideoDriver(super) {}
~VideoDirect3D() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "Direct3D"; }
auto ready() -> bool override { return _ready; }
@@ -19,30 +24,10 @@ struct VideoDirect3D : Video {
auto hasBlocking() -> bool override { return true; }
auto hasSmooth() -> bool override { return true; }
auto setExclusive(bool exclusive) -> bool override {
if(exclusive == Video::exclusive()) return true;
if(!Video::setExclusive(exclusive)) return false;
return initialize();
}
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
return true;
}
auto setSmooth(bool smooth) -> bool override {
if(smooth == Video::smooth()) return true;
if(!Video::setSmooth(smooth)) return false;
if(ready()) updateFilter();
return true;
}
auto setExclusive(bool exclusive) -> bool override { return initialize(); }
auto setContext(uintptr context) -> bool override { return initialize(); }
auto setBlocking(bool blocking) -> bool override { return true; }
auto setSmooth(bool smooth) -> bool override { return updateFilter(); }
auto clear() -> void override {
if(!ready()) return;
@@ -66,7 +51,6 @@ struct VideoDirect3D : Video {
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
if(_lost && !recover()) return false;
//if output size changed, driver must be re-initialized.
@@ -90,14 +74,12 @@ struct VideoDirect3D : Video {
}
auto release() -> void override {
if(!ready()) return;
_surface->UnlockRect();
_surface->Release();
_surface = nullptr;
}
auto output() -> void override {
if(!ready()) return;
if(_lost && !recover()) return;
_device->BeginScene();
@@ -183,13 +165,14 @@ private:
(D3DPOOL)_texturePool, &_texture, nullptr);
}
auto updateFilter() -> void {
if(!_device) return;
if(_lost && !recover()) return;
auto updateFilter() -> bool {
if(!_device) return false;
if(_lost && !recover()) return false;
auto filter = !_smooth ? D3DTEXF_POINT : D3DTEXF_LINEAR;
_device->SetSamplerState(0, D3DSAMP_MINFILTER, filter);
_device->SetSamplerState(0, D3DSAMP_MAGFILTER, filter);
return true;
}
//(x,y) screen coordinates, in pixels

View File

@@ -1,10 +1,15 @@
#include <ddraw.h>
#undef interface
struct VideoDirectDraw : Video {
VideoDirectDraw() { initialize(); }
struct VideoDirectDraw : VideoDriver {
VideoDirectDraw& self = *this;
VideoDirectDraw(Video& super) : VideoDriver(super) {}
~VideoDirectDraw() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "DirectDraw"; }
auto ready() -> bool override { return _ready; }
@@ -12,19 +17,14 @@ struct VideoDirectDraw : Video {
auto hasBlocking() -> bool override { return true; }
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
return true;
}
auto clear() -> void override {
if(!ready()) return;
DDBLTFX fx = {};
fx.dwSize = sizeof(DDBLTFX);
fx.dwFillColor = 0x00000000;
@@ -33,7 +33,6 @@ struct VideoDirectDraw : Video {
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
if(width != _width || height != _height) resize(_width = width, _height = height);
DDSURFACEDESC2 description = {};
description.dwSize = sizeof(DDSURFACEDESC2);
@@ -46,13 +45,11 @@ struct VideoDirectDraw : Video {
}
auto release() -> void override {
if(!ready()) return;
_raster->Unlock(0);
}
auto output() -> void override {
if(!ready()) return;
if(_blocking) while(true) {
if(self.blocking) while(true) {
BOOL vblank;
_interface->GetVerticalBlankStatus(&vblank);
if(vblank) break;
@@ -62,10 +59,10 @@ struct VideoDirectDraw : Video {
SetRect(&source, 0, 0, _width, _height);
POINT point = {0, 0};
ClientToScreen((HWND)_context, &point);
ClientToScreen((HWND)self.context, &point);
RECT target;
GetClientRect((HWND)_context, &target);
GetClientRect((HWND)self.context, &target);
OffsetRect(&target, point.x, point.y);
if(_screen->Blt(&target, _raster, &source, DDBLT_WAIT, 0) == DDERR_SURFACELOST) {
@@ -77,14 +74,14 @@ struct VideoDirectDraw : Video {
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
LPDIRECTDRAW interface = nullptr;
DirectDrawCreate(0, &interface, 0);
interface->QueryInterface(IID_IDirectDraw7, (void**)&_interface);
interface->Release();
_interface->SetCooperativeLevel((HWND)_context, DDSCL_NORMAL);
_interface->SetCooperativeLevel((HWND)self.context, DDSCL_NORMAL);
DDSURFACEDESC2 description = {};
description.dwSize = sizeof(DDSURFACEDESC2);
@@ -93,7 +90,7 @@ private:
_interface->CreateSurface(&description, &_screen, 0);
_interface->CreateClipper(0, &_clipper, 0);
_clipper->SetHWnd(0, (HWND)_context);
_clipper->SetHWnd(0, (HWND)self.context);
_screen->SetClipper(_clipper);
_raster = nullptr;

View File

@@ -1,25 +1,20 @@
struct VideoGDI : Video {
VideoGDI() { initialize(); }
struct VideoGDI : VideoDriver {
VideoGDI& self = *this;
VideoGDI(Video& super) : VideoDriver(super) {}
~VideoGDI() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "GDI"; }
auto ready() -> bool override { return _ready; }
auto hasContext() -> bool override { return true; }
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto clear() -> void override {
if(!ready()) return;
}
auto setContext(uintptr context) -> bool override { return initialize(); }
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
if(!_buffer || _width != width || _height != height) {
if(_buffer) delete[] _buffer;
if(_bitmap) DeleteObject(_bitmap);
@@ -29,11 +24,11 @@ struct VideoGDI : Video {
_width = width;
_height = height;
HDC hdc = GetDC((HWND)_context);
HDC hdc = GetDC((HWND)self.context);
_dc = CreateCompatibleDC(hdc);
_bitmap = CreateCompatibleBitmap(hdc, width, height);
SelectObject(_dc, _bitmap);
ReleaseDC((HWND)_context, hdc);
ReleaseDC((HWND)self.context, hdc);
memory::fill(&_info, sizeof(BITMAPINFO));
_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@@ -50,25 +45,22 @@ struct VideoGDI : Video {
}
auto release() -> void override {
if(!ready()) return;
}
auto output() -> void override {
if(!ready()) return;
RECT rc;
GetClientRect((HWND)_context, &rc);
GetClientRect((HWND)self.context, &rc);
SetDIBits(_dc, _bitmap, 0, _height, (void*)_buffer, &_info, DIB_RGB_COLORS);
HDC hdc = GetDC((HWND)_context);
HDC hdc = GetDC((HWND)self.context);
StretchBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, _dc, 0, 0, _width, _height, SRCCOPY);
ReleaseDC((HWND)_context, hdc);
ReleaseDC((HWND)self.context, hdc);
}
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
_width = 0;
_height = 0;

View File

@@ -7,47 +7,43 @@ auto VideoGLX_X11ErrorHandler(Display*, XErrorEvent*) -> int {
return 0; //suppress errors
}
struct VideoGLX : Video, OpenGL {
VideoGLX() { initialize(); }
struct VideoGLX : VideoDriver, OpenGL {
VideoGLX& self = *this;
VideoGLX(Video& super) : VideoDriver(super) {}
~VideoGLX() { terminate(); }
auto create() -> bool override {
super.setFormat("RGB24");
return initialize();
}
auto driver() -> string override { return "OpenGL"; }
auto ready() -> bool override { return _ready; }
auto hasContext() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasFlush() -> bool override { return true; }
auto hasFormat() -> bool override { return true; }
auto hasSmooth() -> bool override { return true; }
auto hasShader() -> bool override { return true; }
auto availableFormats() -> vector<string> override {
return {"RGB24", "RGB30"};
auto hasFormats() -> vector<string> override {
return {"RGB24"}; //"RGB30"
}
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
if(glXSwapInterval) glXSwapInterval(blocking);
return true;
}
auto setFlush(bool flush) -> bool override {
if(flush == Video::flush()) return true;
if(!Video::setFlush(flush)) return false;
return true;
}
auto setFormat(string format) -> bool override {
if(format == Video::format()) return true;
if(!Video::setFormat(format)) return false;
if(format == "RGB24") {
OpenGL::inputFormat = GL_RGBA8;
return true;
@@ -61,46 +57,37 @@ struct VideoGLX : Video, OpenGL {
return false;
}
auto setSmooth(bool smooth) -> bool override {
if(smooth == Video::smooth()) return true;
if(!Video::setSmooth(smooth)) return false;
if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST;
auto setSmooth(bool) -> bool override {
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto setShader(string shader) -> bool override {
if(shader == Video::shader()) return true;
if(!Video::setShader(shader)) return false;
OpenGL::setShader(shader);
if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST;
auto setShader(string) -> bool override {
OpenGL::setShader(self.shader);
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto clear() -> void override {
if(!ready()) return;
OpenGL::clear();
if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow);
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
OpenGL::size(width, height);
return OpenGL::lock(data, pitch);
}
auto release() -> void override {
if(!ready()) return;
}
auto output() -> void override {
if(!ready()) return;
//we must ensure that the child window is the same size as the parent window.
//unfortunately, we cannot hook the parent window resize event notification,
//as we did not create the parent window, nor have any knowledge of the toolkit used.
//therefore, inelegant as it may be, we query each window size and resize as needed.
XWindowAttributes parent, child;
XGetWindowAttributes(_display, (Window)_context, &parent);
XGetWindowAttributes(_display, (Window)self.context, &parent);
XGetWindowAttributes(_display, (Window)_window, &child);
if(child.width != parent.width || child.height != parent.height) {
XResizeWindow(_display, _window, parent.width, parent.height);
@@ -110,7 +97,7 @@ struct VideoGLX : Video, OpenGL {
OpenGL::outputHeight = parent.height;
OpenGL::output();
if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow);
if(flush()) glFinish();
if(self.flush) glFinish();
}
auto poll() -> void override {
@@ -120,7 +107,7 @@ struct VideoGLX : Video, OpenGL {
if(event.type == Expose) {
XWindowAttributes attributes;
XGetWindowAttributes(_display, _window, &attributes);
doUpdate(attributes.width, attributes.height);
super.doUpdate(attributes.width, attributes.height);
}
}
}
@@ -128,7 +115,7 @@ struct VideoGLX : Video, OpenGL {
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
_display = XOpenDisplay(nullptr);
_screen = DefaultScreen(_display);
@@ -138,11 +125,11 @@ private:
if(_versionMajor < 1 || (_versionMajor == 1 && _versionMinor < 2)) return false;
XWindowAttributes windowAttributes;
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
XGetWindowAttributes(_display, (Window)self.context, &windowAttributes);
int redDepth = Video::format() == "RGB30" ? 10 : 8;
int greenDepth = Video::format() == "RGB30" ? 10 : 8;
int blueDepth = Video::format() == "RGB30" ? 10 : 8;
int redDepth = VideoDriver::format == "RGB30" ? 10 : 8;
int greenDepth = VideoDriver::format == "RGB30" ? 10 : 8;
int blueDepth = VideoDriver::format == "RGB30" ? 10 : 8;
//let GLX determine the best Visual to use for GL output; provide a few hints
//note: some video drivers will override double buffering attribute
@@ -162,7 +149,7 @@ private:
XVisualInfo* vi = glXGetVisualFromFBConfig(_display, fbConfig[0]);
//(Window)_context has already been realized, most likely with DefaultVisual.
//(Window)self.context has already been realized, most likely with DefaultVisual.
//GLX requires that the GL output window has the same Visual as the GLX context.
//it is not possible to change the Visual of an already realized (created) window.
//therefore a new child window, using the same GLX Visual, must be created and binded to it.
@@ -170,7 +157,7 @@ private:
XSetWindowAttributes attributes = {};
attributes.colormap = _colormap;
attributes.border_pixel = 0;
_window = XCreateWindow(_display, /* parent = */ (Window)_context,
_window = XCreateWindow(_display, /* parent = */ (Window)self.context,
/* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height,
/* border_width = */ 0, vi->depth, InputOutput, vi->visual,
CWColormap | CWBorderPixel, &attributes);
@@ -219,7 +206,7 @@ private:
return false;
}
if(glXSwapInterval) glXSwapInterval(_blocking);
if(glXSwapInterval) glXSwapInterval(self.blocking);
//read attributes of frame buffer for later use, as requested attributes from above are not always granted
int value = 0;

View File

@@ -22,6 +22,7 @@
#endif
struct VideoGLX2 : VideoDriver {
VideoGLX2& self = *this;
VideoGLX2(Video& super) : VideoDriver(super) {}
~VideoGLX2() { terminate(); }
@@ -260,8 +261,6 @@ private:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _glWidth, _glHeight, 0, GL_BGRA, _glFormat, _glBuffer);
}
VideoGLX2& self = *this;
bool _ready = false;
Display* _display = nullptr;

View File

@@ -3,10 +3,15 @@
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
struct VideoWGL : Video, OpenGL {
VideoWGL() { initialize(); }
struct VideoWGL : VideoDriver, OpenGL {
VideoWGL& self = *this;
VideoWGL(Video& super) : VideoDriver(super) {}
~VideoWGL() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "OpenGL"; }
auto ready() -> bool override { return _ready; }
@@ -17,70 +22,56 @@ struct VideoWGL : Video, OpenGL {
auto hasShader() -> bool override { return true; }
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
if(wglSwapInterval) wglSwapInterval(blocking);
return true;
}
auto setFlush(bool flush) -> bool override {
if(flush == Video::flush()) return true;
if(!Video::setFlush(flush)) return false;
return true;
}
auto setSmooth(bool smooth) -> bool override {
if(smooth == Video::smooth()) return true;
if(!Video::setSmooth(smooth)) return false;
if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST;
auto setSmooth(bool) -> bool override {
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto setShader(string shader) -> bool override {
if(shader == Video::shader()) return true;
if(!Video::setShader(shader)) return false;
OpenGL::setShader(shader);
if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST;
auto setShader(string) -> bool override {
OpenGL::setShader(self.shader);
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto clear() -> void override {
if(!ready()) return;
OpenGL::clear();
SwapBuffers(_display);
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
OpenGL::size(width, height);
return OpenGL::lock(data, pitch);
}
auto release() -> void override {
if(!ready()) return;
}
auto output() -> void override {
if(!ready()) return;
RECT rectangle;
GetClientRect((HWND)_context, &rectangle);
GetClientRect((HWND)self.context, &rectangle);
OpenGL::outputWidth = rectangle.right - rectangle.left;
OpenGL::outputHeight = rectangle.bottom - rectangle.top;
OpenGL::output();
SwapBuffers(_display);
if(flush()) glFinish();
if(self.flush) glFinish();
}
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
PIXELFORMATDESCRIPTOR descriptor = {};
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
@@ -88,7 +79,7 @@ private:
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
descriptor.iPixelType = PFD_TYPE_RGBA;
_display = GetDC((HWND)_context);
_display = GetDC((HWND)self.context);
GLuint pixelFormat = ChoosePixelFormat(_display, &descriptor);
SetPixelFormat(_display, pixelFormat, &descriptor);
@@ -112,7 +103,7 @@ private:
}
}
if(wglSwapInterval) wglSwapInterval(_blocking);
if(wglSwapInterval) wglSwapInterval(self.blocking);
return _ready = OpenGL::initialize();
}

View File

@@ -9,10 +9,11 @@
#include <X11/extensions/XShm.h>
struct VideoXShm : VideoDriver {
VideoXShm& self = *this;
VideoXShm(Video& super) : VideoDriver(super) {}
~VideoXShm() { terminate(); }
auto create() -> bool {
auto create() -> bool override {
return initialize();
}
@@ -184,8 +185,6 @@ private:
return cr << 16 | cg << 8 | cb << 0;
}
VideoXShm& self = *this;
bool _ready = false;
uint32_t* _inputBuffer = nullptr;

View File

@@ -6,36 +6,35 @@
extern "C" auto XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*) -> XvImage*;
struct VideoXVideo : Video {
VideoXVideo() { initialize(); }
struct VideoXVideo : VideoDriver {
VideoXVideo& self = *this;
VideoXVideo(Video& super) : VideoDriver(super) {}
~VideoXVideo() { terminate(); }
auto create() -> bool override {
return initialize();
}
auto driver() -> string override { return "XVideo"; }
auto ready() -> bool override { return _ready; }
auto hasContext() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasFormat() -> bool override { return true; }
auto availableFormats() -> vector<string> override {
auto hasFormats() -> vector<string> override {
return _formatNames;
}
auto setContext(uintptr context) -> bool override {
if(context == Video::context()) return true;
if(!Video::setContext(context)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == Video::blocking()) return true;
if(!Video::setBlocking(blocking)) return false;
bool result = false;
Display* display = XOpenDisplay(nullptr);
Atom atom = XInternAtom(display, "XV_SYNC_TO_VBLANK", true);
if(atom != None && _port >= 0) {
XvSetPortAttribute(display, _port, atom, _blocking);
XvSetPortAttribute(display, _port, atom, self.blocking);
result = true;
}
XCloseDisplay(display);
@@ -43,13 +42,10 @@ struct VideoXVideo : Video {
}
auto setFormat(string format) -> bool override {
if(format == Video::format()) return true;
if(!Video::setFormat(format)) return false;
return initialize();
}
auto clear() -> void override {
if(!ready()) return;
memory::fill<uint32_t>(_buffer, _bufferWidth * _bufferHeight);
//clear twice in case video is double buffered ...
output();
@@ -57,19 +53,15 @@ struct VideoXVideo : Video {
}
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
if(!ready()) return false;
if(width != _width || height != _height) resize(_width = width, _height = height);
pitch = _bufferWidth * 4;
return data = _buffer;
}
auto release() -> void override {
if(!ready()) return;
}
auto output() -> void override {
if(!ready()) return;
XWindowAttributes target;
XGetWindowAttributes(_display, _window, &target);
@@ -78,7 +70,7 @@ struct VideoXVideo : Video {
//as we did not create the parent window, nor have any knowledge of the toolkit used.
//therefore, query each window size and resize as needed.
XWindowAttributes parent;
XGetWindowAttributes(_display, (Window)_context, &parent);
XGetWindowAttributes(_display, (Window)self.context, &parent);
if(target.width != parent.width || target.height != parent.height) {
XResizeWindow(_display, _window, parent.width, parent.height);
}
@@ -109,7 +101,7 @@ struct VideoXVideo : Video {
if(event.type == Expose) {
XWindowAttributes attributes;
XGetWindowAttributes(_display, _window, &attributes);
doUpdate(attributes.width, attributes.height);
super.doUpdate(attributes.width, attributes.height);
}
}
}
@@ -117,7 +109,7 @@ struct VideoXVideo : Video {
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!self.context) return false;
_display = XOpenDisplay(nullptr);
@@ -154,7 +146,7 @@ private:
//this is so that even if parent window visual depth doesn't match Xv visual
//(common with composited windows), Xv can still render to child window.
XWindowAttributes windowAttributes;
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
XGetWindowAttributes(_display, (Window)self.context, &windowAttributes);
XVisualInfo visualTemplate;
visualTemplate.visualid = visualID;
@@ -169,11 +161,11 @@ private:
return false;
}
_colormap = XCreateColormap(_display, (Window)_context, visualInfo->visual, AllocNone);
_colormap = XCreateColormap(_display, (Window)self.context, visualInfo->visual, AllocNone);
XSetWindowAttributes attributes = {};
attributes.colormap = _colormap;
attributes.border_pixel = 0;
_window = XCreateWindow(_display, /* parent = */ (Window)_context,
_window = XCreateWindow(_display, /* parent = */ (Window)self.context,
/* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height,
/* border_width = */ 0, depth, InputOutput, visualInfo->visual,
CWColormap | CWBorderPixel | CWEventMask, &attributes);
@@ -200,13 +192,13 @@ private:
print("XVideo: unable to find a supported image format.\n");
return false;
}
if(auto match = _formatNames.find(Video::format())) {
if(auto match = _formatNames.find(self.format)) {
_formatID = _formatIDs[match()];
_formatName = _formatNames[match()];
} else {
_formatID = _formatIDs[0];
_formatName = _formatNames[0];
Video::setFormat(_formatName);
self.format = _formatName;
}
_ready = true;