return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
- Surface *surface = new Surface(this, configuration, window);
+ Surface *surface = new WindowSurface(this, configuration, window);
if(!surface->initialize())
{
return success(surface);
}
-EGLSurface Display::createOffscreenSurface(EGLConfig config, const EGLint *attribList)
+EGLSurface Display::createPBufferSurface(EGLConfig config, const EGLint *attribList)
{
EGLint width = 0, height = 0;
EGLenum textureFormat = EGL_NO_TEXTURE;
EGLenum textureTarget = EGL_NO_TEXTURE;
+ EGLBoolean largestPBuffer = EGL_FALSE;
const Config *configuration = mConfigSet.get(config);
if(attribList)
{
while(*attribList != EGL_NONE)
{
- switch (attribList[0])
+ switch(attribList[0])
{
- case EGL_WIDTH:
+ case EGL_WIDTH:
width = attribList[1];
break;
- case EGL_HEIGHT:
+ case EGL_HEIGHT:
height = attribList[1];
break;
- case EGL_LARGEST_PBUFFER:
- if(attribList[1] != EGL_FALSE)
- UNIMPLEMENTED(); // FIXME
+ case EGL_LARGEST_PBUFFER:
+ largestPBuffer = attribList[1];
break;
- case EGL_TEXTURE_FORMAT:
- switch (attribList[1])
+ case EGL_TEXTURE_FORMAT:
+ switch(attribList[1])
{
- case EGL_NO_TEXTURE:
- case EGL_TEXTURE_RGB:
- case EGL_TEXTURE_RGBA:
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
textureFormat = attribList[1];
break;
- default:
+ default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
break;
- case EGL_TEXTURE_TARGET:
- switch (attribList[1])
+ case EGL_TEXTURE_TARGET:
+ switch(attribList[1])
{
- case EGL_NO_TEXTURE:
- case EGL_TEXTURE_2D:
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
textureTarget = attribList[1];
break;
- default:
+ default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
break;
- case EGL_MIPMAP_TEXTURE:
+ case EGL_MIPMAP_TEXTURE:
if(attribList[1] != EGL_FALSE)
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ {
+ return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
break;
- case EGL_VG_COLORSPACE:
+ case EGL_VG_COLORSPACE:
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
- case EGL_VG_ALPHA_FORMAT:
+ case EGL_VG_ALPHA_FORMAT:
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
- default:
+ default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
- Surface *surface = new Surface(this, configuration, width, height, textureFormat, textureTarget);
+ Surface *surface = new PBufferSurface(this, configuration, width, height, textureFormat, textureTarget, largestPBuffer);
if(!surface->initialize())
{
{
for(SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
- if((*surface)->getWindowHandle() == window)
- {
- return true;
- }
+ if((*surface)->isWindowSurface())
+ {
+ if((*surface)->getWindowHandle() == window)
+ {
+ return true;
+ }
+ }
}
return false;
}
-EGLint Display::getMinSwapInterval()
+EGLint Display::getMinSwapInterval() const
{
return mMinSwapInterval;
}
-EGLint Display::getMaxSwapInterval()
+EGLint Display::getMaxSwapInterval() const
{
return mMaxSwapInterval;
}
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);\r
\r
EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);\r
- EGLSurface createOffscreenSurface(EGLConfig config, const EGLint *attribList);\r
+ EGLSurface createPBufferSurface(EGLConfig config, const EGLint *attribList);\r
EGLContext createContext(EGLConfig configHandle, const Context *shareContext, EGLint clientVersion);\r
\r
void destroySurface(Surface *surface);\r
bool isValidWindow(EGLNativeWindowType window);\r
bool hasExistingWindowSurface(EGLNativeWindowType window);\r
\r
- EGLint getMinSwapInterval();\r
- EGLint getMaxSwapInterval();\r
+ EGLint getMinSwapInterval() const;\r
+ EGLint getMaxSwapInterval() const;\r
\r
EGLNativeDisplayType getNativeDisplay() const;\r
const char *getExtensionString() const;\r
namespace egl\r
{\r
\r
-Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window)\r
- : mDisplay(display), mConfig(config), mWindow(window)\r
+Surface::Surface(const Display *display, const Config *config) : display(display), config(config)\r
{\r
- frameBuffer = 0;\r
- backBuffer = 0;\r
-\r
- mDepthStencil = NULL;\r
- mTexture = NULL;\r
- mTextureFormat = EGL_NO_TEXTURE;\r
- mTextureTarget = EGL_NO_TEXTURE;\r
-\r
- mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio\r
- mRenderBuffer = EGL_BACK_BUFFER;\r
- mSwapBehavior = EGL_BUFFER_PRESERVED;\r
- mSwapInterval = -1;\r
- setSwapInterval(1);\r
-}\r
-\r
-Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)\r
- : mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height)\r
-{\r
- frameBuffer = 0;\r
- backBuffer = 0;\r
-\r
- mDepthStencil = NULL;\r
- mWindowSubclassed = false;\r
- mTexture = NULL;\r
- mTextureFormat = textureFormat;\r
- mTextureTarget = textureType;\r
-\r
- mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio\r
- mRenderBuffer = EGL_BACK_BUFFER;\r
- mSwapBehavior = EGL_BUFFER_PRESERVED;\r
- mSwapInterval = -1;\r
+ backBuffer = nullptr;\r
+ depthStencil = nullptr;\r
+ texture = nullptr;\r
+\r
+ width = 0;\r
+ height = 0;\r
+ largestPBuffer = EGL_FALSE;\r
+ pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio\r
+ renderBuffer = EGL_BACK_BUFFER;\r
+ swapBehavior = EGL_BUFFER_PRESERVED;\r
+ textureFormat = EGL_NO_TEXTURE;\r
+ textureTarget = EGL_NO_TEXTURE;\r
+ swapInterval = -1;\r
setSwapInterval(1);\r
}\r
\r
\r
bool Surface::initialize()\r
{\r
- ASSERT(!frameBuffer && !backBuffer && !mDepthStencil);\r
-\r
- return reset();\r
-}\r
-\r
-void Surface::deleteResources()\r
-{\r
- if(mDepthStencil)\r
- {\r
- mDepthStencil->release();\r
- mDepthStencil = NULL;\r
- }\r
-\r
- if(mTexture)\r
- {\r
- mTexture->releaseTexImage();\r
- mTexture = NULL;\r
- }\r
-\r
- if(backBuffer)\r
- {\r
- backBuffer->release();\r
- backBuffer = 0;\r
- }\r
-\r
- delete frameBuffer;\r
- frameBuffer = 0;\r
-}\r
-\r
-bool Surface::reset()\r
-{\r
- if(!mWindow)\r
- {\r
- return reset(mWidth, mHeight);\r
- }\r
-\r
- // FIXME: Wrap into an abstract Window class\r
- #if defined(_WIN32)\r
- RECT windowRect;\r
- GetClientRect(mWindow, &windowRect);\r
-\r
- return reset(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);\r
- #elif defined(__ANDROID__)\r
- return reset(ANativeWindow_getWidth(mWindow), ANativeWindow_getHeight(mWindow));\r
- #else\r
- XWindowAttributes windowAttributes;\r
- libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);\r
-\r
- return reset(windowAttributes.width, windowAttributes.height);\r
- #endif\r
-}\r
-\r
-bool Surface::reset(int backBufferWidth, int backBufferHeight)\r
-{\r
- deleteResources();\r
-\r
- if(mWindow)\r
- {\r
- if(libGLES_CM)\r
- {\r
- frameBuffer = libGLES_CM->createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);\r
- }\r
- else if(libGLESv2)\r
- {\r
- frameBuffer = libGLESv2->createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);\r
- }\r
-\r
- if(!frameBuffer)\r
- {\r
- ERR("Could not create frame buffer");\r
- deleteResources();\r
- return error(EGL_BAD_ALLOC, false);\r
- }\r
- }\r
+ ASSERT(!backBuffer && !depthStencil);\r
\r
if(libGLES_CM)\r
{\r
- backBuffer = libGLES_CM->createBackBuffer(backBufferWidth, backBufferHeight, mConfig);\r
+ backBuffer = libGLES_CM->createBackBuffer(width, height, config);\r
}\r
else if(libGLESv2)\r
{\r
- backBuffer = libGLESv2->createBackBuffer(backBufferWidth, backBufferHeight, mConfig);\r
+ backBuffer = libGLESv2->createBackBuffer(width, height, config);\r
}\r
\r
if(!backBuffer)\r
return error(EGL_BAD_ALLOC, false);\r
}\r
\r
- if(mConfig->mDepthStencilFormat != sw::FORMAT_NULL)\r
+ if(config->mDepthStencilFormat != sw::FORMAT_NULL)\r
{\r
if(libGLES_CM)\r
{\r
- mDepthStencil = libGLES_CM->createDepthStencil(backBufferWidth, backBufferHeight, mConfig->mDepthStencilFormat, 1, false);\r
+ depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, 1, false);\r
}\r
else if(libGLESv2)\r
{\r
- mDepthStencil = libGLESv2->createDepthStencil(backBufferWidth, backBufferHeight, mConfig->mDepthStencilFormat, 1, false);\r
+ depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, 1, false);\r
}\r
\r
- if(!mDepthStencil)\r
+ if(!depthStencil)\r
{\r
ERR("Could not create depth/stencil buffer for surface");\r
deleteResources();\r
}\r
}\r
\r
- mWidth = backBufferWidth;\r
- mHeight = backBufferHeight;\r
-\r
- return true;\r
+ return true;\r
}\r
\r
-EGLNativeWindowType Surface::getWindowHandle()\r
+void Surface::deleteResources()\r
{\r
- return mWindow;\r
-}\r
+ if(depthStencil)\r
+ {\r
+ depthStencil->release();\r
+ depthStencil = nullptr;\r
+ }\r
\r
-void Surface::swap()\r
-{\r
- if(backBuffer)\r
+ if(texture)\r
{\r
- void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);\r
- frameBuffer->flip(source, backBuffer->Surface::getInternalFormat());\r
- backBuffer->unlockInternal();\r
+ texture->releaseTexImage();\r
+ texture = nullptr;\r
+ }\r
\r
- checkForResize();\r
+ if(backBuffer)\r
+ {\r
+ backBuffer->release();\r
+ backBuffer = nullptr;\r
}\r
}\r
\r
\r
egl::Image *Surface::getDepthStencil()\r
{\r
- if(mDepthStencil)\r
+ if(depthStencil)\r
{\r
- mDepthStencil->addRef();\r
+ depthStencil->addRef();\r
}\r
\r
- return mDepthStencil;\r
+ return depthStencil;\r
}\r
\r
void Surface::setSwapBehavior(EGLenum swapBehavior)\r
{\r
- mSwapBehavior = swapBehavior;\r
+ swapBehavior = swapBehavior;\r
}\r
\r
void Surface::setSwapInterval(EGLint interval)\r
{\r
- if(mSwapInterval == interval)\r
+ if(swapInterval == interval)\r
{\r
return;\r
}\r
\r
- mSwapInterval = interval;\r
- mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());\r
- mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());\r
+ swapInterval = interval;\r
+ swapInterval = std::max(swapInterval, display->getMinSwapInterval());\r
+ swapInterval = std::min(swapInterval, display->getMaxSwapInterval());\r
}\r
\r
EGLint Surface::getConfigID() const\r
{\r
- return mConfig->mConfigID;\r
+ return config->mConfigID;\r
}\r
\r
EGLenum Surface::getSurfaceType() const\r
{\r
- return mConfig->mSurfaceType;\r
+ return config->mSurfaceType;\r
}\r
\r
sw::Format Surface::getInternalFormat() const\r
{\r
- return mConfig->mRenderTargetFormat;\r
+ return config->mRenderTargetFormat;\r
}\r
\r
EGLint Surface::getWidth() const\r
{\r
- return mWidth;\r
+ return width;\r
}\r
\r
EGLint Surface::getHeight() const\r
{\r
- return mHeight;\r
+ return height;\r
}\r
\r
EGLint Surface::getPixelAspectRatio() const\r
{\r
- return mPixelAspectRatio;\r
+ return pixelAspectRatio;\r
}\r
\r
EGLenum Surface::getRenderBuffer() const\r
{\r
- return mRenderBuffer;\r
+ return renderBuffer;\r
}\r
\r
EGLenum Surface::getSwapBehavior() const\r
{\r
- return mSwapBehavior;\r
+ return swapBehavior;\r
}\r
\r
EGLenum Surface::getTextureFormat() const\r
{\r
- return mTextureFormat;\r
+ return textureFormat;\r
}\r
\r
EGLenum Surface::getTextureTarget() const\r
{\r
- return mTextureTarget;\r
+ return textureTarget;\r
+}\r
+\r
+EGLBoolean Surface::getLargestPBuffer() const\r
+{\r
+ return largestPBuffer;\r
}\r
\r
void Surface::setBoundTexture(egl::Texture *texture)\r
{\r
- mTexture = texture;\r
+ this->texture = texture;\r
}\r
\r
egl::Texture *Surface::getBoundTexture() const\r
{\r
- return mTexture;\r
+ return texture;\r
}\r
\r
-bool Surface::checkForResize()\r
+WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)\r
+ : Surface(display, config), window(window)\r
+{\r
+ frameBuffer = nullptr;\r
+}\r
+\r
+bool WindowSurface::initialize()\r
+{\r
+ ASSERT(!frameBuffer && !backBuffer && !depthStencil);\r
+\r
+ #if defined(_WIN32)\r
+ RECT windowRect;\r
+ GetClientRect(window, &windowRect);\r
+\r
+ return reset(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);\r
+ #elif defined(__ANDROID__)\r
+ return reset(ANativeWindow_getWidth(window), ANativeWindow_getHeight(window));\r
+ #else\r
+ XWindowAttributes windowAttributes;\r
+ libX11->XGetWindowAttributes(display->getNativeDisplay(), window, &windowAttributes);\r
+\r
+ return reset(windowAttributes.width, windowAttributes.height);\r
+ #endif\r
+}\r
+\r
+void WindowSurface::swap()\r
+{\r
+ if(backBuffer && frameBuffer)\r
+ {\r
+ void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);\r
+ frameBuffer->flip(source, backBuffer->Surface::getInternalFormat());\r
+ backBuffer->unlockInternal();\r
+\r
+ checkForResize();\r
+ }\r
+}\r
+\r
+EGLNativeWindowType WindowSurface::getWindowHandle() const\r
+{\r
+ return window;\r
+}\r
+\r
+bool WindowSurface::checkForResize()\r
{\r
#if defined(_WIN32)\r
RECT client;\r
- if(!GetClientRect(mWindow, &client))\r
+ if(!GetClientRect(window, &client))\r
{\r
ASSERT(false);\r
return false;\r
int clientWidth = client.right - client.left;\r
int clientHeight = client.bottom - client.top;\r
#elif defined(__ANDROID__)\r
- int clientWidth = ANativeWindow_getWidth(mWindow);\r
- int clientHeight = ANativeWindow_getHeight(mWindow);\r
+ int clientWidth = ANativeWindow_getWidth(window);\r
+ int clientHeight = ANativeWindow_getHeight(window);\r
#else\r
XWindowAttributes windowAttributes;\r
- libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);\r
+ libX11->XGetWindowAttributes(display->getNativeDisplay(), window, &windowAttributes);\r
\r
int clientWidth = windowAttributes.width;\r
int clientHeight = windowAttributes.height;\r
#endif\r
\r
- bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();\r
+ bool sizeDirty = (clientWidth != width) || (clientHeight != height);\r
\r
if(sizeDirty)\r
{\r
\r
return false;\r
}\r
+\r
+void WindowSurface::deleteResources()\r
+{\r
+ delete frameBuffer;\r
+ frameBuffer = nullptr;\r
+\r
+ Surface::deleteResources();\r
+}\r
+\r
+bool WindowSurface::reset(int backBufferWidth, int backBufferHeight)\r
+{\r
+ width = backBufferWidth;\r
+ height = backBufferHeight;\r
+\r
+ deleteResources();\r
+\r
+ if(window)\r
+ {\r
+ if(libGLES_CM)\r
+ {\r
+ frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);\r
+ }\r
+ else if(libGLESv2)\r
+ {\r
+ frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);\r
+ }\r
+\r
+ if(!frameBuffer)\r
+ {\r
+ ERR("Could not create frame buffer");\r
+ deleteResources();\r
+ return error(EGL_BAD_ALLOC, false);\r
+ }\r
+ }\r
+\r
+ return Surface::initialize();\r
+}\r
+\r
+PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)\r
+ : Surface(display, config)\r
+{\r
+ this->width = width;\r
+ this->height = height;\r
+ this->largestPBuffer = largestPBuffer;\r
+}\r
+\r
+void PBufferSurface::swap()\r
+{\r
+ // No effect\r
+}\r
+\r
+EGLNativeWindowType PBufferSurface::getWindowHandle() const\r
+{\r
+ UNREACHABLE(-1); // Should not be called. Only WindowSurface has a window handle.\r
+\r
+ return 0;\r
+}\r
+\r
}\r
class Surface : public gl::Object\r
{\r
public:\r
- Surface(Display *display, const egl::Config *config, EGLNativeWindowType window);\r
- Surface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);\r
-\r
- bool initialize();\r
- void swap();\r
-\r
- EGLNativeWindowType getWindowHandle();\r
+ virtual bool initialize();\r
+ virtual void swap() = 0;\r
\r
virtual egl::Image *getRenderTarget();\r
virtual egl::Image *getDepthStencil();\r
virtual EGLenum getSwapBehavior() const;\r
virtual EGLenum getTextureFormat() const;\r
virtual EGLenum getTextureTarget() const;\r
+ virtual EGLBoolean getLargestPBuffer() const;\r
+ virtual EGLNativeWindowType getWindowHandle() const = 0;\r
\r
virtual void setBoundTexture(egl::Texture *texture);\r
virtual egl::Texture *getBoundTexture() const;\r
\r
- bool checkForResize(); // Returns true if surface changed due to resize\r
+ virtual bool isWindowSurface() const { return false; }\r
+ virtual bool isPBufferSurface() const { return false; }\r
+\r
+protected:\r
+ Surface(const Display *display, const Config *config);\r
\r
-private:\r
virtual ~Surface();\r
\r
- void deleteResources();\r
- bool reset();\r
+ virtual void deleteResources();\r
\r
- Display *const mDisplay;\r
- egl::Image *mDepthStencil;\r
- sw::FrameBuffer *frameBuffer;\r
- egl::Image *backBuffer;\r
- egl::Texture *mTexture;\r
+ const Display *const display;\r
+ Image *depthStencil;\r
+ Image *backBuffer;\r
+ Texture *texture;\r
\r
bool reset(int backbufferWidth, int backbufferHeight);\r
- \r
- const EGLNativeWindowType mWindow; // Window that the surface is created for.\r
- bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking\r
- const egl::Config *mConfig; // EGL config surface was created with\r
- EGLint mHeight; // Height of surface\r
- EGLint mWidth; // Width of surface\r
-// EGLint horizontalResolution; // Horizontal dot pitch\r
-// EGLint verticalResolution; // Vertical dot pitch\r
-// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible\r
-// EGLBoolean mipmapTexture; // True if texture has mipmaps\r
-// EGLint mipmapLevel; // Mipmap level to render to\r
-// EGLenum multisampleResolve; // Multisample resolve behavior\r
- EGLint mPixelAspectRatio; // Display aspect ratio\r
- EGLenum mRenderBuffer; // Render buffer\r
- EGLenum mSwapBehavior; // Buffer swap behavior\r
- EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture\r
- EGLenum mTextureTarget; // Type of texture: 2D or no texture\r
-// EGLenum vgAlphaFormat; // Alpha format for OpenVG\r
-// EGLenum vgColorSpace; // Color space for OpenVG\r
- EGLint mSwapInterval;\r
+ \r
+ const Config *const config; // EGL config surface was created with\r
+ EGLint height; // Height of surface\r
+ EGLint width; // Width of surface\r
+// EGLint horizontalResolution; // Horizontal dot pitch\r
+// EGLint verticalResolution; // Vertical dot pitch\r
+ EGLBoolean largestPBuffer; // If true, create largest pbuffer possible\r
+// EGLBoolean mipmapTexture; // True if texture has mipmaps\r
+// EGLint mipmapLevel; // Mipmap level to render to\r
+// EGLenum multisampleResolve; // Multisample resolve behavior\r
+ EGLint pixelAspectRatio; // Display aspect ratio\r
+ EGLenum renderBuffer; // Render buffer\r
+ EGLenum swapBehavior; // Buffer swap behavior\r
+ EGLenum textureFormat; // Format of texture: RGB, RGBA, or no texture\r
+ EGLenum textureTarget; // Type of texture: 2D or no texture\r
+// EGLenum vgAlphaFormat; // Alpha format for OpenVG\r
+// EGLenum vgColorSpace; // Color space for OpenVG\r
+ EGLint swapInterval;\r
+};\r
+\r
+class WindowSurface : public Surface\r
+{\r
+public:\r
+ WindowSurface(Display *display, const egl::Config *config, EGLNativeWindowType window);\r
+\r
+ bool initialize() override;\r
+\r
+ bool isWindowSurface() const override { return true; }\r
+ void swap() override;\r
+\r
+ EGLNativeWindowType getWindowHandle() const override;\r
+\r
+private:\r
+ void deleteResources() override;\r
+ bool checkForResize();\r
+ bool reset(int backBufferWidth, int backBufferHeight);\r
+\r
+ const EGLNativeWindowType window;\r
+ sw::FrameBuffer *frameBuffer;\r
+};\r
+\r
+class PBufferSurface : public Surface\r
+{\r
+public:\r
+ PBufferSurface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget, EGLBoolean largestPBuffer);\r
+\r
+ bool isPBufferSurface() const override { return true; }\r
+ void swap() override;\r
+\r
+ EGLNativeWindowType getWindowHandle() const override;\r
};\r
}\r
\r
return EGL_NO_SURFACE;\r
}\r
\r
- return display->createOffscreenSurface(config, attrib_list);\r
+ return display->createPBufferSurface(config, attrib_list);\r
}\r
\r
EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)\r
UNIMPLEMENTED(); // FIXME\r
break;\r
case EGL_LARGEST_PBUFFER:\r
- UNIMPLEMENTED(); // FIXME\r
+ if(eglSurface->isPBufferSurface()) // For a window or pixmap surface, the contents of *value are not modified.\r
+ {\r
+ *value = eglSurface->getLargestPBuffer(); \r
+ }\r
break;\r
case EGL_MIPMAP_TEXTURE:\r
UNIMPLEMENTED(); // FIXME\r
return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
}\r
\r
- if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
+ if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())\r
{\r
return error(EGL_BAD_SURFACE, EGL_FALSE);\r
}\r
return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
}\r
\r
- if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
+ if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())\r
{\r
return error(EGL_BAD_SURFACE, EGL_FALSE);\r
}\r
}\r
else\r
{\r
- applyTexture(samplerType, samplerIndex, 0);\r
+ applyTexture(samplerType, samplerIndex, nullptr);\r
\r
device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);\r
device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);\r
}\r
else\r
{\r
- applyTexture(samplerType, samplerIndex, NULL);\r
+ applyTexture(samplerType, samplerIndex, nullptr);\r
}\r
}\r
}\r
}\r
else\r
{\r
- applyTexture(unit, 0);\r
+ applyTexture(unit, nullptr);\r
\r
device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);\r
device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);\r
}\r
\r
intptr_t offset = reinterpret_cast<intptr_t>(indices);\r
- bool alignedOffset = false;\r
\r
if(buffer != NULL)\r
{\r
- switch(type)\r
- {\r
- case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;\r
- case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;\r
- default: UNREACHABLE(type); alignedOffset = false;\r
- }\r
-\r
if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))\r
{\r
return GL_INVALID_OPERATION;\r
}\r
else\r
{\r
- applyTexture(samplerType, samplerIndex, 0);\r
+ applyTexture(samplerType, samplerIndex, nullptr);\r
}\r
}\r
else\r
{\r
- applyTexture(samplerType, samplerIndex, NULL);\r
+ applyTexture(samplerType, samplerIndex, nullptr);\r
}\r
}\r
}\r
}\r
\r
intptr_t offset = reinterpret_cast<intptr_t>(indices);\r
- bool alignedOffset = false;\r
\r
if(buffer != NULL)\r
{\r
- switch(type)\r
- {\r
- case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;\r
- case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;\r
- case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;\r
- default: UNREACHABLE(type); alignedOffset = false;\r
- }\r
-\r
if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))\r
{\r
return GL_INVALID_OPERATION;\r
if(compressed)\r
{\r
if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
- (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
+ (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
{\r
return error(GL_INVALID_OPERATION, false);\r
}\r
}\r
\r
if(xoffset + width > texture->getWidth(target, level) ||\r
- yoffset + height > texture->getHeight(target, level))\r
+ yoffset + height > texture->getHeight(target, level))\r
{\r
return error(GL_INVALID_VALUE, false);\r
}\r
}\r
\r
if(xoffset + width > texture->getWidth(target, level) ||\r
- yoffset + height > texture->getHeight(target, level))\r
+ yoffset + height > texture->getHeight(target, level))\r
{\r
return error(GL_INVALID_VALUE, false);\r
}\r
if(compressed)\r
{\r
if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
- (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
- (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
+ (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
+ (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
{\r
return error(GL_INVALID_OPERATION, false);\r
}\r
{\r
case GL_ALPHA:\r
if(colorbufferFormat != GL_ALPHA &&\r
- colorbufferFormat != GL_RGBA &&\r
- colorbufferFormat != GL_RGBA4 &&\r
- colorbufferFormat != GL_RGB5_A1 &&\r
- colorbufferFormat != GL_RGBA8)\r
+ colorbufferFormat != GL_RGBA &&\r
+ colorbufferFormat != GL_RGBA4 &&\r
+ colorbufferFormat != GL_RGB5_A1 &&\r
+ colorbufferFormat != GL_RGBA8)\r
{\r
return error(GL_INVALID_OPERATION, false);\r
}\r
case GL_LUMINANCE:\r
case GL_RGB:\r
if(colorbufferFormat != GL_RGB &&\r
- colorbufferFormat != GL_RGB565 &&\r
- colorbufferFormat != GL_RGB8 &&\r
- colorbufferFormat != GL_RGBA &&\r
- colorbufferFormat != GL_RGBA4 &&\r
- colorbufferFormat != GL_RGB5_A1 &&\r
- colorbufferFormat != GL_RGBA8)\r
+ colorbufferFormat != GL_RGB565 &&\r
+ colorbufferFormat != GL_RGB8 &&\r
+ colorbufferFormat != GL_RGBA &&\r
+ colorbufferFormat != GL_RGBA4 &&\r
+ colorbufferFormat != GL_RGB5_A1 &&\r
+ colorbufferFormat != GL_RGBA8)\r
{\r
return error(GL_INVALID_OPERATION, false);\r
}\r
case GL_LUMINANCE_ALPHA:\r
case GL_RGBA:\r
if(colorbufferFormat != GL_RGBA &&\r
- colorbufferFormat != GL_RGBA4 &&\r
- colorbufferFormat != GL_RGB5_A1 &&\r
- colorbufferFormat != GL_RGBA8)\r
+ colorbufferFormat != GL_RGBA4 &&\r
+ colorbufferFormat != GL_RGB5_A1 &&\r
+ colorbufferFormat != GL_RGBA8)\r
{\r
return error(GL_INVALID_OPERATION, false);\r
}\r