Commit bb6e6643 by Geoff Lang Committed by Commit Bot

Implement EGL_surfaceless_context for Android/ChromeOS and optimize eglMakeCurrent

BUG=angleproject:1651 Change-Id: I13c1a669d83098e22c0d7fb003d13beacc20c4ae Reviewed-on: https://chromium-review.googlesource.com/623947Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent bb2bbfbb
......@@ -105,6 +105,9 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Surfaceless contexts are emulated even if there is no native support.
outExtensions->surfacelessContext = true;
}
void DisplayEGL::generateCaps(egl::Caps *outCaps) const
......
......@@ -15,9 +15,8 @@ PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, context, renderer)
: SurfaceEGL(state, egl, config, attribList, renderer)
{
}
......
......@@ -24,7 +24,6 @@ class PbufferSurfaceEGL : public SurfaceEGL
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer);
~PbufferSurfaceEGL() override;
......
......@@ -17,14 +17,12 @@ SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer)
: SurfaceGL(state, renderer),
mEGL(egl),
mConfig(config),
mAttribList(attribList),
mSurface(EGL_NO_SURFACE),
mContext(context)
mSurface(EGL_NO_SURFACE)
{
}
......@@ -39,11 +37,7 @@ SurfaceEGL::~SurfaceEGL()
egl::Error SurfaceEGL::makeCurrent()
{
EGLBoolean success = mEGL->makeCurrent(mSurface, mContext);
if (success == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
}
// Handling of makeCurrent is done in DisplayEGL
return egl::NoError();
}
......@@ -133,4 +127,9 @@ EGLint SurfaceEGL::getSwapBehavior() const
return value;
}
EGLSurface SurfaceEGL::getSurface() const
{
return mSurface;
}
} // namespace rx
......@@ -24,7 +24,6 @@ class SurfaceEGL : public SurfaceGL
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer);
~SurfaceEGL() override;
......@@ -44,14 +43,13 @@ class SurfaceEGL : public SurfaceGL
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
EGLSurface getSurface() const;
protected:
const FunctionsEGL *mEGL;
EGLConfig mConfig;
std::vector<EGLint> mAttribList;
EGLSurface mSurface;
private:
EGLContext mContext;
};
} // namespace rx
......
......@@ -16,9 +16,8 @@ WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state,
EGLConfig config,
EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, context, renderer), mWindow(window)
: SurfaceEGL(state, egl, config, attribList, renderer), mWindow(window)
{
}
......
......@@ -22,7 +22,6 @@ class WindowSurfaceEGL : public SurfaceEGL
EGLConfig config,
EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
EGLContext context,
RendererGL *renderer);
~WindowSurfaceEGL() override;
......
......@@ -33,7 +33,7 @@ namespace rx
{
DisplayAndroid::DisplayAndroid(const egl::DisplayState &state)
: DisplayEGL(state), mDummyPbuffer(EGL_NO_SURFACE)
: DisplayEGL(state), mDummyPbuffer(EGL_NO_SURFACE), mCurrentSurface(EGL_NO_SURFACE)
{
}
......@@ -114,6 +114,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display)
return egl::EglNotInitialized()
<< "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
}
mCurrentSurface = mDummyPbuffer;
mFunctionsGL = mEGL->makeFunctionsGL();
mFunctionsGL->initialize();
......@@ -130,6 +131,7 @@ void DisplayAndroid::terminate()
{
ERR() << "eglMakeCurrent error " << egl::Error(mEGL->getError());
}
mCurrentSurface = EGL_NO_SURFACE;
if (mDummyPbuffer != EGL_NO_SURFACE)
{
......@@ -173,8 +175,7 @@ SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state,
success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1);
return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), mContext,
getRenderer());
return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), getRenderer());
}
SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
......@@ -188,8 +189,7 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state
success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1);
return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), mContext,
getRenderer());
return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), getRenderer());
}
SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
......@@ -394,5 +394,32 @@ egl::Error DisplayAndroid::waitNative(const gl::Context *context, EGLint engine)
UNIMPLEMENTED();
return egl::NoError();
}
egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface,
egl::Surface *readSurface,
gl::Context *context)
{
if (drawSurface)
{
SurfaceEGL *drawSurfaceEGL = GetImplAs<SurfaceEGL>(drawSurface);
EGLSurface surface = drawSurfaceEGL->getSurface();
if (surface != mCurrentSurface)
{
if (mEGL->makeCurrent(surface, mContext) == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
}
mCurrentSurface = surface;
}
}
return DisplayGL::makeCurrent(drawSurface, readSurface, context);
}
egl::Error DisplayAndroid::makeCurrentSurfaceless(gl::Context *context)
{
// Nothing to do because EGL always uses the same context and the previous surface can be left
// current.
return egl::NoError();
}
} // namespace rx
......@@ -56,7 +56,13 @@ class DisplayAndroid : public DisplayEGL
egl::Error waitClient(const gl::Context *context) const override;
egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
egl::Error makeCurrent(egl::Surface *drawSurface,
egl::Surface *readSurface,
gl::Context *context) override;
private:
egl::Error makeCurrentSurfaceless(gl::Context *context) override;
template <typename T>
void getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const;
......@@ -70,6 +76,7 @@ class DisplayAndroid : public DisplayEGL
std::vector<EGLint> mConfigAttribList;
std::map<EGLint, EGLint> mConfigIds;
EGLSurface mDummyPbuffer;
EGLSurface mCurrentSurface;
};
} // namespace rx
......
......@@ -955,4 +955,10 @@ void DisplayOzone::setSwapInterval(EGLSurface drawable, SwapControlData *data)
ASSERT(data != nullptr);
}
egl::Error DisplayOzone::makeCurrentSurfaceless(gl::Context *context)
{
// Nothing to do, handled in the GL layers
return egl::NoError();
}
} // namespace rx
......@@ -145,6 +145,8 @@ class DisplayOzone final : public DisplayEGL
void setSwapInterval(EGLSurface drawable, SwapControlData *data);
private:
egl::Error makeCurrentSurfaceless(gl::Context *context) override;
GLuint makeShader(GLuint type, const char *src);
void drawBuffer(Buffer *buffer);
void drawWithBlit(Buffer *buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment