Commit 26a717b0 by Corentin Wallez Committed by Commit Bot

GL: Emulate SRGB blits where needed.

Desktop OpenGL before 4.4 doesn't handle SRGB blits the same way OpenGL ES does. Emulate them by drawing a quad. BUG=angleproject:1492 BUG=chromium:634525 Change-Id: I9f2992d9b373941b10f19f8a51564f0f756cc4df Reviewed-on: https://chromium-review.googlesource.com/389853Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent b80a5e9c
......@@ -44,6 +44,15 @@ struct Vector4
float w;
};
struct Vector2
{
Vector2() {}
Vector2(float x, float y) : x(x), y(y) {}
float x;
float y;
};
inline bool isPow2(int x)
{
return (x & (x - 1)) == 0 && (x != 0);
......
......@@ -58,6 +58,9 @@ BlitGL::BlitGL(const FunctionsGL *functions,
mWorkarounds(workarounds),
mStateManager(stateManager),
mBlitProgram(0),
mSourceTextureLocation(-1),
mScaleLocation(-1),
mOffsetLocation(-1),
mScratchFBO(0),
mVAO(0)
{
......@@ -142,7 +145,6 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture,
const gl::InternalFormat &internalFormatInfo =
gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat);
mStateManager->activeTexture(0);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.x,
sourceArea.y, sourceArea.width, sourceArea.height, 0);
......@@ -167,7 +169,6 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture,
mScratchTextures[1], 0);
// Render to the destination texture, sampling from the scratch texture
mStateManager->useProgram(mBlitProgram);
mStateManager->setViewport(gl::Rectangle(0, 0, sourceArea.width, sourceArea.height));
mStateManager->setScissorTestEnabled(false);
mStateManager->setDepthRange(0.0f, 1.0f);
......@@ -182,9 +183,19 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture,
mStateManager->setRasterizerDiscardEnabled(false);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
mStateManager->activeTexture(0);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
mStateManager->useProgram(mBlitProgram);
mFunctions->uniform1i(mSourceTextureLocation, 0);
mFunctions->uniform2f(mScaleLocation, 1.0, 1.0);
mFunctions->uniform2f(mOffsetLocation, 0.0, 0.0);
mStateManager->bindVertexArray(mVAO, 0);
mFunctions->drawArrays(GL_TRIANGLES, 0, 6);
mFunctions->drawArrays(GL_TRIANGLES, 0, 3);
// Copy the swizzled texture to the destination texture
mStateManager->bindTexture(textureType, texture);
......@@ -192,10 +203,170 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture,
0, sourceArea.width, sourceArea.height);
// Finally orphan the scratch textures so they can be GCed by the driver.
orphanScratchTextures();
return gl::NoError();
}
gl::Error BlitGL::blitColorBufferWithShader(const gl::Framebuffer *source,
const gl::Framebuffer *dest,
const gl::Rectangle &sourceAreaIn,
const gl::Rectangle &destAreaIn,
GLenum filter)
{
ANGLE_TRY(initializeResources());
// Normalize the destination area to have positive width and height because we will use
// glViewport to set it, which doesn't allow negative width or height.
gl::Rectangle sourceArea = sourceAreaIn;
gl::Rectangle destArea = destAreaIn;
if (destArea.width < 0)
{
destArea.x += destArea.width;
destArea.width = -destArea.width;
sourceArea.x += sourceArea.width;
sourceArea.width = -sourceArea.width;
}
if (destArea.height < 0)
{
destArea.y += destArea.height;
destArea.height = -destArea.height;
sourceArea.y += sourceArea.height;
sourceArea.height = -sourceArea.height;
}
const gl::FramebufferAttachment *readAttachment = source->getReadColorbuffer();
ASSERT(readAttachment->getSamples() <= 1);
// Compute the part of the source that will be sampled.
gl::Rectangle inBoundsSource;
{
gl::Extents sourceSize = readAttachment->getSize();
gl::Rectangle sourceBounds(0, 0, sourceSize.width, sourceSize.height);
gl::ClipRectangle(sourceArea, sourceBounds, &inBoundsSource);
// Note that inBoundsSource will have lost the orientation information.
ASSERT(inBoundsSource.width >= 0 && inBoundsSource.height >= 0);
// Early out when the sampled part is empty as the blit will be a noop,
// and it prevents a division by zero in later computations.
if (inBoundsSource.width == 0 || inBoundsSource.height == 0)
{
return gl::NoError();
}
}
// The blit will be emulated by getting the source of the blit in a texture and sampling it
// with CLAMP_TO_EDGE. The quad used to draw can trivially compute texture coordinates going
// from (0, 0) to (1, 1). These texture coordinates will need to be transformed to make two
// regions match:
// - The region of the texture representing the source framebuffer region that will be sampled
// - The region of the drawn quad that corresponds to non-clamped blit, this is the same as the
// region of the source rectangle that is inside the source attachment.
//
// These two regions, T (texture) and D (dest) are defined by their offset in texcoord space
// in (0, 1)^2 and their size in texcoord space in (-1, 1)^2. The size can be negative to
// represent the orientation of the blit.
//
// Then if P is the quad texcoord, Q the texcoord inside T, and R the texture texcoord:
// - Q = (P - D.offset) / D.size
// - Q = (R - T.offset) / T.size
// Hence R = (P - D.offset) / D.size * T.size - T.offset
// = P * (T.size / D.size) + (T.offset - D.offset * T.size / D.size)
GLuint textureId;
gl::Vector2 TOffset;
gl::Vector2 TSize;
// TODO(cwallez) once texture dirty bits are landed, reuse attached texture instead of using
// CopyTexImage2D
{
textureId = mScratchTextures[0];
TOffset = gl::Vector2(0.0, 0.0);
TSize = gl::Vector2(1.0, 1.0);
if (sourceArea.width < 0)
{
TOffset.x = 1.0;
TSize.x = -1.0;
}
if (sourceArea.height < 0)
{
TOffset.y = 1.0;
TSize.y = -1.0;
}
GLenum format = readAttachment->getFormat().info->internalFormat;
const FramebufferGL *sourceGL = GetImplAs<FramebufferGL>(source);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceGL->getFramebufferID());
mStateManager->bindTexture(GL_TEXTURE_2D, textureId);
mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, format, inBoundsSource.x, inBoundsSource.y,
inBoundsSource.width, inBoundsSource.height, 0);
}
// Compute normalized sampled draw quad region
// It is the same as the region of the source rectangle that is in bounds.
gl::Vector2 DOffset;
gl::Vector2 DSize;
{
ASSERT(sourceArea.width != 0 && sourceArea.height != 0);
gl::Rectangle orientedInBounds = inBoundsSource;
if (sourceArea.width < 0)
{
orientedInBounds.x += orientedInBounds.width;
orientedInBounds.width = -orientedInBounds.width;
}
if (sourceArea.height < 0)
{
orientedInBounds.y += orientedInBounds.height;
orientedInBounds.height = -orientedInBounds.height;
}
DOffset =
gl::Vector2(static_cast<float>(orientedInBounds.x - sourceArea.x) / sourceArea.width,
static_cast<float>(orientedInBounds.y - sourceArea.y) / sourceArea.height);
DSize = gl::Vector2(static_cast<float>(orientedInBounds.width) / sourceArea.width,
static_cast<float>(orientedInBounds.height) / sourceArea.height);
}
ASSERT(DSize.x != 0.0 && DSize.y != 0.0);
gl::Vector2 texCoordScale = gl::Vector2(TSize.x / DSize.x, TSize.y / DSize.y);
gl::Vector2 texCoordOffset = gl::Vector2(TOffset.x - DOffset.x * texCoordScale.x,
TOffset.y - DOffset.y * texCoordScale.y);
// Reset all the state except scissor and viewport
mStateManager->setDepthRange(0.0f, 1.0f);
mStateManager->setBlendEnabled(false);
mStateManager->setColorMask(true, true, true, true);
mStateManager->setSampleAlphaToCoverageEnabled(false);
mStateManager->setSampleCoverageEnabled(false);
mStateManager->setDepthTestEnabled(false);
mStateManager->setStencilTestEnabled(false);
mStateManager->setCullFaceEnabled(false);
mStateManager->setPolygonOffsetFillEnabled(false);
mStateManager->setRasterizerDiscardEnabled(false);
// Use the viewport to draw exactly to the destination rectangle
mStateManager->setViewport(destArea);
// Set uniforms
setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, filter);
setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, filter);
setScratchTextureParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
setScratchTextureParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
mStateManager->activeTexture(0);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[1]);
mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
mStateManager->useProgram(mBlitProgram);
mFunctions->uniform1i(mSourceTextureLocation, 0);
mFunctions->uniform2f(mScaleLocation, texCoordScale.x, texCoordScale.y);
mFunctions->uniform2f(mOffsetLocation, texCoordOffset.x, texCoordOffset.y);
const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest);
mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destGL->getFramebufferID());
mStateManager->bindVertexArray(mVAO, 0);
mFunctions->drawArrays(GL_TRIANGLES, 0, 3);
return gl::NoError();
}
......@@ -207,25 +378,25 @@ gl::Error BlitGL::initializeResources()
mBlitProgram = mFunctions->createProgram();
// Compile the fragment shader
// It uses a single, large triangle, to avoid arithmetic precision issues where fragments
// with the same Y coordinate don't get exactly the same interpolated texcoord Y.
const char *vsSource =
"#version 150\n"
"out vec2 v_texcoord;\n"
"uniform vec2 u_scale;\n"
"uniform vec2 u_offset;\n"
"\n"
"void main()\n"
"{\n"
" const vec2 quad_positions[6] = vec2[6]\n"
" const vec2 quad_positions[3] = vec2[3]\n"
" (\n"
" vec2(0.0f, 0.0f),\n"
" vec2(0.0f, 1.0f),\n"
" vec2(1.0f, 0.0f),\n"
"\n"
" vec2(0.0f, 1.0f),\n"
" vec2(1.0f, 0.0f),\n"
" vec2(1.0f, 1.0f)\n"
" vec2(-0.5f, 0.0f),\n"
" vec2( 1.5f, 0.0f),\n"
" vec2( 0.5f, 2.0f)\n"
" );\n"
"\n"
" gl_Position = vec4((quad_positions[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);\n"
" v_texcoord = quad_positions[gl_VertexID];\n"
" v_texcoord = quad_positions[gl_VertexID] * u_scale + u_offset;\n"
"}\n";
GLuint vs = mFunctions->createShader(GL_VERTEX_SHADER);
......@@ -237,6 +408,8 @@ gl::Error BlitGL::initializeResources()
mFunctions->deleteShader(vs);
// Compile the vertex shader
// It discards if the texcoord is outside (0, 1)^2 so the blitframebuffer workaround
// doesn't write when the point sampled is outside of the source framebuffer.
const char *fsSource =
"#version 150\n"
"uniform sampler2D u_source_texture;\n"
......@@ -245,6 +418,10 @@ gl::Error BlitGL::initializeResources()
"\n"
"void main()\n"
"{\n"
" if (clamp(v_texcoord, vec2(0.0), vec2(1.0)) != v_texcoord)\n"
" {\n"
" discard;\n"
" }\n"
" output_color = texture(u_source_texture, v_texcoord);\n"
"}\n";
......@@ -259,9 +436,10 @@ gl::Error BlitGL::initializeResources()
mFunctions->linkProgram(mBlitProgram);
ANGLE_TRY(CheckLinkStatus(mFunctions, mBlitProgram));
GLuint textureUniform = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture");
mSourceTextureLocation = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture");
mScaleLocation = mFunctions->getUniformLocation(mBlitProgram, "u_scale");
mOffsetLocation = mFunctions->getUniformLocation(mBlitProgram, "u_offset");
mStateManager->useProgram(mBlitProgram);
mFunctions->uniform1i(textureUniform, 0);
}
for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
......@@ -269,11 +447,6 @@ gl::Error BlitGL::initializeResources()
if (mScratchTextures[i] == 0)
{
mFunctions->genTextures(1, &mScratchTextures[i]);
mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[i]);
// Use nearest, non-mipmapped sampling with the scratch texture
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
}
......@@ -289,4 +462,25 @@ gl::Error BlitGL::initializeResources()
return gl::NoError();
}
void BlitGL::orphanScratchTextures()
{
for (auto texture : mScratchTextures)
{
mStateManager->bindTexture(GL_TEXTURE_2D, texture);
mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
}
}
void BlitGL::setScratchTextureParameter(GLenum param, GLenum value)
{
for (auto texture : mScratchTextures)
{
mStateManager->bindTexture(GL_TEXTURE_2D, texture);
mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
}
}
} // namespace rx
......@@ -52,14 +52,26 @@ class BlitGL : public angle::NonCopyable
const gl::Rectangle &sourceArea,
const gl::Framebuffer *source);
gl::Error blitColorBufferWithShader(const gl::Framebuffer *source,
const gl::Framebuffer *dest,
const gl::Rectangle &sourceArea,
const gl::Rectangle &destArea,
GLenum filter);
gl::Error initializeResources();
private:
void orphanScratchTextures();
void setScratchTextureParameter(GLenum param, GLenum value);
const FunctionsGL *mFunctions;
const WorkaroundsGL &mWorkarounds;
StateManagerGL *mStateManager;
GLuint mBlitProgram;
GLint mSourceTextureLocation;
GLint mScaleLocation;
GLint mOffsetLocation;
GLuint mScratchTextures[2];
GLuint mScratchFBO;
......
......@@ -62,7 +62,8 @@ ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
{
return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(), false);
return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(),
mRenderer->getBlitter(), false);
}
TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
......
......@@ -16,6 +16,7 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/gl/BlitGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/RenderbufferGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
......@@ -35,11 +36,13 @@ FramebufferGL::FramebufferGL(const FramebufferState &state,
const FunctionsGL *functions,
StateManagerGL *stateManager,
const WorkaroundsGL &workarounds,
BlitGL *blitter,
bool isDefault)
: FramebufferImpl(state),
mFunctions(functions),
mStateManager(stateManager),
mWorkarounds(workarounds),
mBlitter(blitter),
mFramebufferID(0),
mIsDefault(isDefault)
{
......@@ -53,11 +56,13 @@ FramebufferGL::FramebufferGL(GLuint id,
const FramebufferState &state,
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
BlitGL *blitter,
StateManagerGL *stateManager)
: FramebufferImpl(state),
mFunctions(functions),
mStateManager(stateManager),
mWorkarounds(workarounds),
mBlitter(blitter),
mFramebufferID(id),
mIsDefault(true)
{
......@@ -276,15 +281,81 @@ Error FramebufferGL::blit(ContextImpl *context,
GLenum filter)
{
const Framebuffer *sourceFramebuffer = context->getGLState().getReadFramebuffer();
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer);
const Framebuffer *destFramebuffer = context->getGLState().getDrawFramebuffer();
bool needManualColorBlit = false;
// The manual SRGB blit is only needed to perform correct linear interpolation. We don't
// need to make sure there is SRGB conversion for NEAREST as the values will be copied.
if (filter != GL_NEAREST)
{
// Prior to OpenGL 4.4 BlitFramebuffer (section 18.3.1 of GL 4.3 core profile) reads:
// When values are taken from the read buffer, no linearization is performed, even
// if the format of the buffer is SRGB.
// Starting from OpenGL 4.4 (section 18.3.1) it reads:
// When values are taken from the read buffer, if FRAMEBUFFER_SRGB is enabled and the
// value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment
// corresponding to the read buffer is SRGB, the red, green, and blue components are
// converted from the non-linear sRGB color space according [...].
{
const FramebufferAttachment *readAttachment = sourceFramebuffer->getReadColorbuffer();
bool sourceSRGB =
readAttachment != nullptr && readAttachment->getColorEncoding() == GL_SRGB;
needManualColorBlit =
needManualColorBlit || (sourceSRGB && !mFunctions->isAtLeastGL(gl::Version(4, 4)));
}
// Prior to OpenGL 4.2 BlitFramebuffer (section 4.3.2 of GL 4.1 core profile) reads:
// Blit operations bypass the fragment pipeline. The only fragment operations which
// affect a blit are the pixel ownership test and scissor test.
// Starting from OpenGL 4.2 (section 4.3.2) it reads:
// When values are written to the draw buffers, blit operations bypass the fragment
// pipeline. The only fragment operations which affect a blit are the pixel ownership
// test, the scissor test and sRGB conversion.
if (!needManualColorBlit)
{
bool destSRGB = false;
for (size_t i = 0; i < destFramebuffer->getDrawbufferStateCount(); ++i)
{
const FramebufferAttachment *attachment = destFramebuffer->getDrawBuffer(i);
if (attachment && attachment->getColorEncoding() == GL_SRGB)
{
destSRGB = true;
break;
}
}
needManualColorBlit =
needManualColorBlit || (destSRGB && !mFunctions->isAtLeastGL(gl::Version(4, 2)));
}
}
// Enable FRAMEBUFFER_SRGB if needed
syncDrawState();
GLenum blitMask = mask;
if (needManualColorBlit && (mask & GL_COLOR_BUFFER_BIT))
{
ANGLE_TRY(mBlitter->blitColorBufferWithShader(sourceFramebuffer, destFramebuffer,
sourceArea, destArea, filter));
blitMask &= ~GL_COLOR_BUFFER_BIT;
}
if (blitMask == 0)
{
return gl::NoError();
}
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID);
mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x1(), sourceArea.y1(),
destArea.x, destArea.y, destArea.x1(), destArea.y1(), mask, filter);
destArea.x, destArea.y, destArea.x1(), destArea.y1(), blitMask,
filter);
return Error(GL_NO_ERROR);
return gl::NoError();
}
bool FramebufferGL::checkStatus() const
......@@ -370,17 +441,17 @@ void FramebufferGL::syncClearState(GLbitfield mask)
if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments &&
(mask & GL_COLOR_BUFFER_BIT) != 0 && !mIsDefault)
{
bool hasSRBAttachment = false;
bool hasSRGBAttachment = false;
for (const auto &attachment : mState.getColorAttachments())
{
if (attachment.isAttached() && attachment.getColorEncoding() == GL_SRGB)
{
hasSRBAttachment = true;
hasSRGBAttachment = true;
break;
}
}
mStateManager->setFramebufferSRGBEnabled(hasSRBAttachment);
mStateManager->setFramebufferSRGBEnabled(hasSRGBAttachment);
}
else
{
......
......@@ -14,6 +14,7 @@
namespace rx
{
class BlitGL;
class FunctionsGL;
class StateManagerGL;
struct WorkaroundsGL;
......@@ -25,6 +26,7 @@ class FramebufferGL : public FramebufferImpl
const FunctionsGL *functions,
StateManagerGL *stateManager,
const WorkaroundsGL &workarounds,
BlitGL *blitter,
bool isDefault);
// Constructor called when we need to create a FramebufferGL from an
// existing framebuffer name, for example for the default framebuffer
......@@ -33,6 +35,7 @@ class FramebufferGL : public FramebufferImpl
const gl::FramebufferState &data,
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
BlitGL *blitter,
StateManagerGL *stateManager);
~FramebufferGL() override;
......@@ -100,6 +103,7 @@ class FramebufferGL : public FramebufferImpl
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
const WorkaroundsGL &mWorkarounds;
BlitGL *mBlitter;
GLuint mFramebufferID;
bool mIsDefault;
......
......@@ -26,6 +26,6 @@ SurfaceGL::~SurfaceGL()
FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::FramebufferState &data)
{
return new FramebufferGL(data, mRenderer->getFunctions(), mRenderer->getStateManager(),
mRenderer->getWorkarounds(), true);
mRenderer->getWorkarounds(), mRenderer->getBlitter(), true);
}
}
......@@ -53,7 +53,7 @@ class PbufferSurfaceCGL : public SurfaceGL
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
const WorkaroundsGL &mWorkarounds;
RendererGL *mRenderer;
GLuint mFramebuffer;
GLuint mColorRenderbuffer;
......
......@@ -28,7 +28,7 @@ PbufferSurfaceCGL::PbufferSurfaceCGL(const egl::SurfaceState &state,
mHeight(height),
mFunctions(functions),
mStateManager(renderer->getStateManager()),
mWorkarounds(renderer->getWorkarounds()),
mRenderer(renderer),
mFramebuffer(0),
mColorRenderbuffer(0),
mDSRenderbuffer(0)
......@@ -136,7 +136,8 @@ EGLint PbufferSurfaceCGL::getSwapBehavior() const
FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
{
// TODO(cwallez) assert it happens only once?
return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mStateManager);
return new FramebufferGL(mFramebuffer, state, mFunctions, mRenderer->getWorkarounds(),
mRenderer->getBlitter(), mStateManager);
}
}
......@@ -88,6 +88,7 @@ class WindowSurfaceCGL : public SurfaceGL
CGLContextObj mContext;
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
RendererGL *mRenderer;
const WorkaroundsGL &mWorkarounds;
GLuint mFramebuffer;
......
......@@ -154,11 +154,12 @@
mContext(context),
mFunctions(functions),
mStateManager(renderer->getStateManager()),
mRenderer(renderer),
mWorkarounds(renderer->getWorkarounds()),
mFramebuffer(0),
mDSRenderbuffer(0)
{
pthread_mutex_init(&mSwapState.mutex, nullptr);
{
pthread_mutex_init(&mSwapState.mutex, nullptr);
}
WindowSurfaceCGL::~WindowSurfaceCGL()
......@@ -324,7 +325,8 @@ EGLint WindowSurfaceCGL::getSwapBehavior() const
FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
{
// TODO(cwallez) assert it happens only once?
return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mStateManager);
return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mRenderer->getBlitter(),
mStateManager);
}
}
......@@ -308,9 +308,9 @@ uint32_t DisplayOzone::Buffer::getDRMFB()
FramebufferGL *DisplayOzone::Buffer::framebufferGL(const gl::FramebufferState &state)
{
return new FramebufferGL(mGLFB, state, mDisplay->mFunctionsGL,
mDisplay->getRenderer()->getWorkarounds(),
mDisplay->getRenderer()->getStateManager());
return new FramebufferGL(
mGLFB, state, mDisplay->mFunctionsGL, mDisplay->getRenderer()->getWorkarounds(),
mDisplay->getRenderer()->getBlitter(), mDisplay->getRenderer()->getStateManager());
}
void DisplayOzone::Buffer::present()
......
......@@ -36,6 +36,7 @@ DXGISwapChainWindowSurfaceWGL::DXGISwapChainWindowSurfaceWGL(const egl::SurfaceS
mWindow(window),
mStateManager(renderer->getStateManager()),
mWorkarounds(renderer->getWorkarounds()),
mRenderer(renderer),
mFunctionsGL(functionsGL),
mFunctionsWGL(functionsWGL),
mDevice(device),
......@@ -292,7 +293,8 @@ EGLint DXGISwapChainWindowSurfaceWGL::getSwapBehavior() const
FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer(
const gl::FramebufferState &data)
{
return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds, mStateManager);
return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds,
mRenderer->getBlitter(), mStateManager);
}
egl::Error DXGISwapChainWindowSurfaceWGL::setObjectsLocked(bool locked)
......
......@@ -66,6 +66,7 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceGL
StateManagerGL *mStateManager;
const WorkaroundsGL &mWorkarounds;
RendererGL *mRenderer;
const FunctionsGL *mFunctionsGL;
const FunctionsWGL *mFunctionsWGL;
......
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