1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include "mactexturemanager.h"
#include <qevent.h>
/*!
Since we are using client storage which means asynchronous DMA
uploads, we need to keep the bits around for the duration
of the texture id. So we keep the image in along in the reference
*/
class QSGMacTextureReference : public TextureReference
{
public:
void timerEvent(QTimerEvent *t) {
setStatus(TextureReference::Uploaded);
killTimer(t->timerId());
--inProgress;
}
QImage image;
bool big;
static int inProgress;
};
int QSGMacTextureReference::inProgress = 0;
QSGMacTextureManager::QSGMacTextureManager()
{
}
const TextureReference *QSGMacTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
{
// Client storage will most likely fail when mipmapping is used..
if (hints & TextureManager::GenerateMipmapUploadHint)
return TextureManager::requestUploadedTexture(image, hints, listener, slot);
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, image.constBits());
glBindTexture(GL_TEXTURE_2D, 0);
QSGMacTextureReference *texture = new QSGMacTextureReference;
if (listener && slot) {
QObject::connect(texture, SIGNAL(statusChanged(int)), listener, slot);
}
texture->image = image;
texture->setTextureId(id);
texture->setTextureSize(image.size());
texture->setOwnsTexture(true);
if (hints & TextureManager::SynchronousUploadHint) {
texture->setStatus(TextureReference::Uploaded);
} else {
// Delay "big" images
int byteSize = image.height() * image.bytesPerLine();
if (byteSize > 500000) {
texture->setStatus(TextureReference::Uploading);
++QSGMacTextureReference::inProgress;
int delay = byteSize / 50000 * QSGMacTextureReference::inProgress;
texture->startTimer(delay);
} else {
texture->setStatus(TextureReference::Uploaded);
}
}
return texture;
}
|