winrt: Refactor backing store
Thanks to new features in ANGLE, the backing store implementation complexity can be greatly reduced. By using ES3 framebuffer blit, no shader code is required, and the shader loading code and blit shader can be removed. Change-Id: Iab3d915e279ad6468a75ef6257794f12acd8cb65 Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
parent
1a9701fe81
commit
c7abf81786
@ -1,14 +0,0 @@
|
|||||||
uniform SamplerState Sampler : register(s0);
|
|
||||||
uniform Texture2D Texture : register(t0);
|
|
||||||
|
|
||||||
void blitvs(in float4 pos0 : TEXCOORD0, in float2 tex0 : TEXCOORD1,
|
|
||||||
out float4 gl_Position : SV_POSITION, out float2 coord : TEXCOORD0)
|
|
||||||
{
|
|
||||||
coord = tex0;
|
|
||||||
gl_Position = pos0 * float4(1.0, -1.0, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 blitps(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0
|
|
||||||
{
|
|
||||||
return Texture.Sample(Sampler, coord);
|
|
||||||
}
|
|
@ -45,343 +45,136 @@
|
|||||||
#include "qwinrtwindow.h"
|
#include "qwinrtwindow.h"
|
||||||
#include "qwinrteglcontext.h"
|
#include "qwinrteglcontext.h"
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
|
#include <QtGui/QOpenGLFramebufferObject>
|
||||||
|
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES3/gl3ext.h>
|
||||||
|
|
||||||
// Generated shader headers
|
|
||||||
#include "blitps.h"
|
|
||||||
#include "blitvs.h"
|
|
||||||
|
|
||||||
namespace { // Utility namespace for writing out an ANGLE-compatible binary blob
|
|
||||||
|
|
||||||
// Must match packaged ANGLE
|
|
||||||
enum : quint32 {
|
|
||||||
AngleMajorVersion = 1,
|
|
||||||
AngleMinorVersion = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShaderString
|
|
||||||
{
|
|
||||||
ShaderString(const char *data = 0) : data(data) { }
|
|
||||||
const char *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ANGLE stream compatibility - when size_t is 32-bit, QDataStream::writeBytes() also works
|
|
||||||
QDataStream &operator<<(QDataStream &stream, const ShaderString &shaderString)
|
|
||||||
{
|
|
||||||
if (!shaderString.data)
|
|
||||||
return stream << size_t(0);
|
|
||||||
|
|
||||||
size_t len = strlen(shaderString.data);
|
|
||||||
stream << len;
|
|
||||||
stream.writeRawData(shaderString.data, int(len));
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Attribute
|
|
||||||
{
|
|
||||||
Attribute(GLenum type = 0, const char *name = 0, quint32 index = 0)
|
|
||||||
: type(type), name(name), index(index) { }
|
|
||||||
GLenum type;
|
|
||||||
ShaderString name;
|
|
||||||
quint32 index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sampler
|
|
||||||
{
|
|
||||||
enum TextureType { Texture2D, TextureCube };
|
|
||||||
Sampler(bool active = false, GLint unit = 0, TextureType type = Texture2D)
|
|
||||||
: active(active), unit(unit), type(type) { }
|
|
||||||
bool active;
|
|
||||||
GLint unit;
|
|
||||||
TextureType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Uniform
|
|
||||||
{
|
|
||||||
Uniform() { }
|
|
||||||
Uniform(GLenum type, quint32 precision, const char *name, quint32 arraySize,
|
|
||||||
quint32 psRegisterIndex, quint32 vsRegisterIndex, quint32 registerCount)
|
|
||||||
: type(type), precision(precision), name(name), arraySize(arraySize)
|
|
||||||
, psRegisterIndex(psRegisterIndex), vsRegisterIndex(vsRegisterIndex), registerCount(registerCount) { }
|
|
||||||
GLenum type;
|
|
||||||
quint32 precision;
|
|
||||||
ShaderString name;
|
|
||||||
quint32 arraySize;
|
|
||||||
quint32 psRegisterIndex;
|
|
||||||
quint32 vsRegisterIndex;
|
|
||||||
quint32 registerCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UniformIndex
|
|
||||||
{
|
|
||||||
UniformIndex(const char *name = 0, quint32 element = 0, quint32 index = 0)
|
|
||||||
: name(name), element(element), index(index) { }
|
|
||||||
ShaderString name;
|
|
||||||
quint32 element;
|
|
||||||
quint32 index;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QByteArray createAngleBinary(
|
|
||||||
const QVector<Attribute> &attributes,
|
|
||||||
const QVector<Sampler> &textureSamplers,
|
|
||||||
const QVector<Sampler> &vertexSamplers,
|
|
||||||
const QVector<Uniform> &uniforms,
|
|
||||||
const QVector<UniformIndex> &uniformIndex,
|
|
||||||
const QByteArray &pixelShader,
|
|
||||||
const QByteArray &vertexShader,
|
|
||||||
const QByteArray &geometryShader = QByteArray(),
|
|
||||||
bool usesPointSize = false)
|
|
||||||
{
|
|
||||||
QByteArray binary;
|
|
||||||
|
|
||||||
QDataStream stream(&binary, QIODevice::WriteOnly);
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
|
|
||||||
stream << quint32(GL_PROGRAM_BINARY_ANGLE)
|
|
||||||
<< qint32(AngleMajorVersion)
|
|
||||||
<< qint32(AngleMinorVersion);
|
|
||||||
|
|
||||||
// Vertex attributes
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
if (i < attributes.size())
|
|
||||||
stream << quint32(attributes[i].type) << attributes[i].name << attributes[i].index;
|
|
||||||
else
|
|
||||||
stream << quint32(GL_NONE) << ShaderString() << qint32(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Texture units
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
if (i < textureSamplers.size())
|
|
||||||
stream << textureSamplers[i].active << textureSamplers[i].unit << qint32(textureSamplers[i].type);
|
|
||||||
else
|
|
||||||
stream << false << qint32(0) << qint32(Sampler::Texture2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertex texture units
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
if (i < vertexSamplers.size())
|
|
||||||
stream << vertexSamplers[i].active << vertexSamplers[i].unit << qint32(vertexSamplers[i].type);
|
|
||||||
else
|
|
||||||
stream << false << qint32(0) << qint32(Sampler::Texture2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
stream << vertexSamplers.size()
|
|
||||||
<< textureSamplers.size()
|
|
||||||
<< usesPointSize;
|
|
||||||
|
|
||||||
stream << size_t(uniforms.size());
|
|
||||||
foreach (const Uniform &uniform, uniforms) {
|
|
||||||
stream << uniform.type << uniform.precision << uniform.name << uniform.arraySize
|
|
||||||
<< uniform.psRegisterIndex << uniform.vsRegisterIndex << uniform.registerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream << size_t(uniformIndex.size());
|
|
||||||
foreach (const UniformIndex &index, uniformIndex)
|
|
||||||
stream << index.name << index.element << index.index;
|
|
||||||
|
|
||||||
stream << quint32(pixelShader.size())
|
|
||||||
<< quint32(vertexShader.size())
|
|
||||||
<< quint32(geometryShader.size());
|
|
||||||
|
|
||||||
stream.writeRawData(pixelShader.constData(), pixelShader.size());
|
|
||||||
stream.writeRawData(vertexShader.constData(), vertexShader.size());
|
|
||||||
if (!geometryShader.isEmpty())
|
|
||||||
stream.writeRawData(geometryShader.constData(), geometryShader.size());
|
|
||||||
|
|
||||||
return binary;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static const GLfloat normCoords[] = { -1, 1, 1, 1, 1, -1, -1, -1 };
|
class QWinRTBackingStorePrivate
|
||||||
static const GLfloat quadCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
|
{
|
||||||
|
public:
|
||||||
|
bool initialized;
|
||||||
|
QSize size;
|
||||||
|
QScopedPointer<QOpenGLContext> context;
|
||||||
|
QScopedPointer<QOpenGLFramebufferObject> fbo;
|
||||||
|
QWinRTScreen *screen;
|
||||||
|
QImage paintDevice;
|
||||||
|
};
|
||||||
|
|
||||||
QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
|
QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
|
||||||
: QPlatformBackingStore(window)
|
: QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate)
|
||||||
, m_context(new QOpenGLContext)
|
|
||||||
, m_shaderProgram(0)
|
|
||||||
, m_fbo(0)
|
|
||||||
, m_texture(0)
|
|
||||||
, m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
|
|
||||||
, m_initialized(false)
|
|
||||||
{
|
{
|
||||||
|
Q_D(QWinRTBackingStore);
|
||||||
|
|
||||||
|
d->initialized = false;
|
||||||
|
d->screen = static_cast<QWinRTScreen*>(window->screen()->handle());
|
||||||
|
|
||||||
window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
|
window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWinRTBackingStore::initialize()
|
bool QWinRTBackingStore::initialize()
|
||||||
{
|
{
|
||||||
if (m_initialized)
|
Q_D(QWinRTBackingStore);
|
||||||
|
|
||||||
|
if (d->initialized)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
m_context->setFormat(window()->requestedFormat());
|
d->context.reset(new QOpenGLContext);
|
||||||
m_context->setScreen(window()->screen());
|
QSurfaceFormat format = window()->requestedFormat();
|
||||||
if (!m_context->create())
|
format.setVersion(3, 0); // Required for ES3 framebuffer blit
|
||||||
|
d->context->setFormat(format);
|
||||||
|
d->context->setScreen(window()->screen());
|
||||||
|
if (!d->context->create())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!m_context->makeCurrent(window()))
|
if (!d->context->makeCurrent(window()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
glGenFramebuffers(1, &m_fbo);
|
d->context->doneCurrent();
|
||||||
glGenRenderbuffers(1, &m_rbo);
|
d->initialized = true;
|
||||||
glGenTextures(1, &m_texture);
|
|
||||||
m_shaderProgram = glCreateProgram();
|
|
||||||
|
|
||||||
#if 0 // Standard GLES passthrough shader program
|
|
||||||
static const char *vertexShaderSource =
|
|
||||||
"attribute vec4 pos0;\n"
|
|
||||||
"attribute vec2 tex0;\n"
|
|
||||||
"varying vec2 coord;\n"
|
|
||||||
"void main() {\n"
|
|
||||||
" coord = tex0;\n"
|
|
||||||
" gl_Position = pos0;\n"
|
|
||||||
"}\n";
|
|
||||||
static const char *fragmentShaderSource =
|
|
||||||
"uniform sampler2D texture;\n"
|
|
||||||
"varying highp vec2 coord;\n"
|
|
||||||
"void main() {\n"
|
|
||||||
" gl_FragColor = texture2D(texture, coord);\n"
|
|
||||||
"}\n";
|
|
||||||
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
|
|
||||||
glCompileShader(vertexShader);
|
|
||||||
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
|
|
||||||
glCompileShader(fragmentShader);
|
|
||||||
glAttachShader(m_shaderProgram, vertexShader);
|
|
||||||
glAttachShader(m_shaderProgram, fragmentShader);
|
|
||||||
glLinkProgram(m_shaderProgram);
|
|
||||||
#else // Precompiled passthrough shader
|
|
||||||
QVector<Attribute> attributes = QVector<Attribute>() << Attribute(GL_FLOAT_VEC4, "pos0", 0)
|
|
||||||
<< Attribute(GL_FLOAT_VEC2, "tex0", 1);
|
|
||||||
QVector<Sampler> textureSamplers = QVector<Sampler>() << Sampler(true, 0, Sampler::Texture2D);
|
|
||||||
QVector<Sampler> vertexSamplers;
|
|
||||||
QVector<Uniform> uniforms = QVector<Uniform>() << Uniform(GL_SAMPLER_2D, 0, "texture", 0, 0, -1, 1);
|
|
||||||
QVector<UniformIndex> uniformsIndex = QVector<UniformIndex>() << UniformIndex("texture", 0, 0);
|
|
||||||
QByteArray pixelShader(reinterpret_cast<const char *>(q_blitps), sizeof(q_blitps));
|
|
||||||
QByteArray vertexShader(reinterpret_cast<const char *>(q_blitvs), sizeof(q_blitvs));
|
|
||||||
QByteArray binary = createAngleBinary(attributes, textureSamplers, vertexSamplers,
|
|
||||||
uniforms, uniformsIndex, pixelShader, vertexShader);
|
|
||||||
glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
|
|
||||||
#endif
|
|
||||||
m_context->doneCurrent();
|
|
||||||
m_initialized = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWinRTBackingStore::~QWinRTBackingStore()
|
QWinRTBackingStore::~QWinRTBackingStore()
|
||||||
{
|
{
|
||||||
if (!m_initialized)
|
|
||||||
return;
|
|
||||||
glDeleteBuffers(1, &m_fbo);
|
|
||||||
glDeleteRenderbuffers(1, &m_rbo);
|
|
||||||
glDeleteTextures(1, &m_texture);
|
|
||||||
glDeleteProgram(m_shaderProgram);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPaintDevice *QWinRTBackingStore::paintDevice()
|
QPaintDevice *QWinRTBackingStore::paintDevice()
|
||||||
{
|
{
|
||||||
return &m_paintDevice;
|
Q_D(QWinRTBackingStore);
|
||||||
|
return &d->paintDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||||
{
|
{
|
||||||
|
Q_D(QWinRTBackingStore);
|
||||||
Q_UNUSED(offset)
|
Q_UNUSED(offset)
|
||||||
if (m_size.isEmpty())
|
|
||||||
|
if (d->size.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_context->makeCurrent(window);
|
const bool ok = d->context->makeCurrent(window);
|
||||||
|
if (!ok)
|
||||||
|
qWarning("unable to flush");
|
||||||
|
|
||||||
// Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
|
const QRect bounds = region.boundingRect();
|
||||||
// Since we're blitting the whole width anyway, the boundingRect() is used in the assumption that
|
glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
|
||||||
// we don't repeat upload. This is of course dependent on the distance between update regions.
|
// TODO: when ANGLE GLES3 support is finished, use the glPixelStorei functions to minimize upload
|
||||||
// Ideally, we would use the GL_EXT_unpack_subimage extension, which should be possible to implement
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), d->size.width(), bounds.height(),
|
||||||
// since D3D11_MAPPED_SUBRESOURCE supports RowPitch (see below).
|
GL_RGBA, GL_UNSIGNED_BYTE, d->paintDevice.constScanLine(bounds.y()));
|
||||||
// Note that single-line blits in a loop are *very* slow, so reducing calls to glTexSubImage2D
|
|
||||||
// is probably a good idea anyway.
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
|
||||||
QRect bounds = region.boundingRect();
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
|
|
||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_paintDevice.constScanLine(bounds.y()));
|
|
||||||
// TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
|
|
||||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
|
|
||||||
//glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
|
|
||||||
// GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()) + bounds.x() * 4);
|
|
||||||
|
|
||||||
// Bind render buffer
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
|
|
||||||
|
|
||||||
// Bind position
|
|
||||||
glUseProgram(m_shaderProgram);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, normCoords);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
|
|
||||||
|
|
||||||
// Render
|
|
||||||
const QSize blitSize = m_size * window->devicePixelRatio();
|
|
||||||
glViewport(0, 0, blitSize.width(), blitSize.height());
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
|
|
||||||
// Unbind
|
|
||||||
glDisableVertexAttribArray(0);
|
|
||||||
glDisableVertexAttribArray(1);
|
|
||||||
glUseProgram(0);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
// fast blit - TODO: perform the blit inside swap buffers instead
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, d->fbo->handle());
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
|
const int y1 = bounds.height() + bounds.y();
|
||||||
glBlitFramebufferANGLE(0, 0, blitSize.width(), blitSize.height(), // TODO: blit only the changed rectangle
|
const int y2 = d->size.height() - y1;
|
||||||
0, 0, blitSize.width(), blitSize.height(),
|
const int x1 = bounds.x();
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
const int x2 = x1 + bounds.width();
|
||||||
|
glBlitFramebuffer(x1, y2, x2, y1,
|
||||||
|
x1, y1, x2, y2,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
m_context->swapBuffers(window);
|
d->context->swapBuffers(window);
|
||||||
m_context->doneCurrent();
|
d->context->doneCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||||
{
|
{
|
||||||
|
Q_D(QWinRTBackingStore);
|
||||||
Q_UNUSED(staticContents)
|
Q_UNUSED(staticContents)
|
||||||
|
|
||||||
if (!initialize())
|
if (!initialize())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_size == size)
|
if (d->size == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_size = size;
|
d->size = size;
|
||||||
if (m_size.isEmpty())
|
if (d->size.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_paintDevice = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
|
d->paintDevice = QImage(d->size, QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
|
||||||
m_context->makeCurrent(window());
|
const bool ok = d->context->makeCurrent(window());
|
||||||
// Input texture
|
if (!ok)
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
qWarning("unable to resize");
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
|
|
||||||
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
|
d->fbo.reset(new QOpenGLFramebufferObject(d->size));
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
d->context->doneCurrent();
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
}
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
QImage QWinRTBackingStore::toImage() const
|
||||||
// Render buffer
|
{
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
|
Q_D(const QWinRTBackingStore);
|
||||||
const QSize blitSize = m_size * window()->devicePixelRatio();
|
return d->paintDevice;
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, blitSize.width(), blitSize.height());
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
||||||
m_context->doneCurrent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWinRTBackingStore::beginPaint(const QRegion ®ion)
|
void QWinRTBackingStore::beginPaint(const QRegion ®ion)
|
||||||
{
|
{
|
||||||
Q_UNUSED(region)
|
resize(window()->size(), region);
|
||||||
resize(window()->size(), QRegion());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWinRTBackingStore::endPaint()
|
void QWinRTBackingStore::endPaint()
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QWinRTScreen;
|
class QWinRTScreen;
|
||||||
class QOpenGLContext;
|
|
||||||
|
|
||||||
|
class QWinRTBackingStorePrivate;
|
||||||
class QWinRTBackingStore : public QPlatformBackingStore
|
class QWinRTBackingStore : public QPlatformBackingStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -60,19 +60,13 @@ public:
|
|||||||
void endPaint();
|
void endPaint();
|
||||||
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset);
|
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset);
|
||||||
void resize(const QSize &size, const QRegion &staticContents);
|
void resize(const QSize &size, const QRegion &staticContents);
|
||||||
QImage toImage() const Q_DECL_OVERRIDE { return m_paintDevice; }
|
QImage toImage() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initialize();
|
bool initialize();
|
||||||
bool m_initialized;
|
|
||||||
QSize m_size;
|
QScopedPointer<QWinRTBackingStorePrivate> d_ptr;
|
||||||
QScopedPointer<QOpenGLContext> m_context;
|
Q_DECLARE_PRIVATE(QWinRTBackingStore)
|
||||||
quint32 m_shaderProgram;
|
|
||||||
quint32 m_fbo;
|
|
||||||
quint32 m_rbo;
|
|
||||||
quint32 m_texture;
|
|
||||||
QWinRTScreen *m_screen;
|
|
||||||
QImage m_paintDevice;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -56,26 +56,9 @@ HEADERS = \
|
|||||||
qwinrttheme.h \
|
qwinrttheme.h \
|
||||||
qwinrtwindow.h
|
qwinrtwindow.h
|
||||||
|
|
||||||
|
|
||||||
BLIT_INPUT = $$PWD/blit.hlsl
|
|
||||||
fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
|
|
||||||
fxc_blitps.output = $$OUT_PWD/blitps.h
|
|
||||||
fxc_blitps.input = BLIT_INPUT
|
|
||||||
fxc_blitps.dependency_type = TYPE_C
|
|
||||||
fxc_blitps.variable_out = HEADERS
|
|
||||||
fxc_blitps.CONFIG += target_predeps
|
|
||||||
fxc_blitvs.commands = fxc.exe /nologo /T vs_4_0_level_9_1 /E blitvs /Vn q_blitvs /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
|
|
||||||
fxc_blitvs.output = $$OUT_PWD/blitvs.h
|
|
||||||
fxc_blitvs.input = BLIT_INPUT
|
|
||||||
fxc_blitvs.dependency_type = TYPE_C
|
|
||||||
fxc_blitvs.variable_out = HEADERS
|
|
||||||
fxc_blitvs.CONFIG += target_predeps
|
|
||||||
QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
|
|
||||||
|
|
||||||
winphone:equals(WINSDK_VER, 8.0): {
|
winphone:equals(WINSDK_VER, 8.0): {
|
||||||
SOURCES -= qwinrtplatformmessagedialoghelper.cpp
|
SOURCES -= qwinrtplatformmessagedialoghelper.cpp
|
||||||
HEADERS -= qwinrtplatformmessagedialoghelper.h
|
HEADERS -= qwinrtplatformmessagedialoghelper.h
|
||||||
}
|
}
|
||||||
|
|
||||||
OTHER_FILES += winrt.json \
|
OTHER_FILES += winrt.json
|
||||||
blit.hlsl
|
|
||||||
|
Loading…
Reference in New Issue
Block a user