9 #define LOC QString("OpenGL: ")
24 static inline int __glCheck__(
const QString &loc,
const char* fileName,
int n)
26 int error = glGetError();
29 LOG(VB_GENERAL, LOG_ERR, QString(
"%1: %2 @ %3, %4")
30 .arg(loc).arg(error).arg(fileName).arg(n));
35 #define MAX_VERTEX_CACHE 500
36 #define glCheck() __glCheck__(LOC, __FILE__, __LINE__)
54 format.setDepth(
false);
56 bool setswapinterval =
false;
57 int synctovblank = -1;
65 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Could not determine whether Sync "
66 "to VBlank is enabled.");
68 else if (synctovblank == 0)
76 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Sync to VBlank is enabled (good!)");
80 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Forcing swap interval for OS X.");
81 setswapinterval =
true;
85 format.setSwapInterval(1);
92 if (painter.contains(
"opengl2"))
107 : QGLContext(format, device),
MythRender(type)
128 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Initialised MythRenderOpenGL");
133 bool recommended =
true;
135 QString renderer = (
const char*) glGetString(GL_RENDERER);
136 if (!(this->
format().directRendering()))
138 LOG(VB_GENERAL, LOG_WARNING,
LOC +
139 "OpenGL is using software rendering.");
142 else if (renderer.contains(
"Software Rasterizer", Qt::CaseInsensitive))
144 LOG(VB_GENERAL, LOG_WARNING,
LOC +
145 "OpenGL is using software rasterizer.");
148 else if (renderer.contains(
"softpipe", Qt::CaseInsensitive))
150 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL seems to be using software "
151 "fallback. Please check your OpenGL driver installation, "
152 "configuration, and device permissions.");
161 if (
this != MythRenderOpenGL::currentContext())
172 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Mis-matched calls to makeCurrent()");
178 #if !defined(Q_OS_WIN)
186 QWidget *parent = (QWidget*)this->device();
188 parent->setGeometry(rect);
241 uint32_t
tmp = (r << 24) + (g << 16) + (b << 8) + a;
247 glClearColor(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
258 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Using GL_APPLE_fence");
264 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Using GL_NV_fence");
286 m_textures[tex].m_data_size, NULL, GL_STREAM_DRAW);
293 unsigned char *scratch =
new unsigned char[
m_textures[tex].m_data_size];
296 memset(scratch, 0, m_textures[tex].m_data_size);
297 m_textures[tex].m_data = scratch;
330 static bool rects =
true;
331 static bool check =
true;
335 rects = !getenv(
"OPENGL_NORECT");
337 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling NPOT textures.");
340 int ret = GL_TEXTURE_2D;
342 if (
m_extensions.contains(
"GL_NV_texture_rectangle") && rects)
343 ret = GL_TEXTURE_RECTANGLE_NV;
344 else if (
m_extensions.contains(
"GL_ARB_texture_rectangle") && rects)
345 ret = GL_TEXTURE_RECTANGLE_ARB;
346 else if (
m_extensions.contains(
"GL_EXT_texture_rectangle") && rects)
347 ret = GL_TEXTURE_RECTANGLE_EXT;
349 rect = (ret != GL_TEXTURE_2D);
355 if (type == GL_TEXTURE_RECTANGLE_NV || type == GL_TEXTURE_RECTANGLE_ARB ||
356 type == GL_TEXTURE_RECTANGLE_EXT)
376 glGenTextures(1, &tex);
377 glBindTexture(type, tex);
386 texture.
m_size = tot_size;
420 while (w < size.width())
425 while (h < size.height())
454 if (filt == GL_LINEAR_MIPMAP_LINEAR && !mipmaps)
462 glBindTexture(type, tex);
463 uint mag_filt = filt;
464 if (filt == GL_LINEAR_MIPMAP_LINEAR)
466 mag_filt = GL_LINEAR;
467 glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
468 glTexParameteri(type, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
470 glTexParameteri(type, GL_TEXTURE_MIN_FILTER, filt);
471 glTexParameteri(type, GL_TEXTURE_MAG_FILTER, mag_filt);
472 glTexParameteri(type, GL_TEXTURE_WRAP_S, wrap);
473 if (type != GL_TEXTURE_1D)
474 glTexParameteri(type, GL_TEXTURE_WRAP_T, wrap);
494 float w0 = (((-1 * x + 3) * x - 3) * x + 1) / 6;
495 float w1 = ((( 3 * x - 6) * x + 0) * x + 4) / 6;
496 float w2 = (((-3 * x + 3) * x + 3) * x + 1) / 6;
497 float w3 = ((( 1 * x + 0) * x + 0) * x + 0) / 6;
498 *dst++ = 1 + x - w1 / (w0 + w1);
499 *dst++ = 1 - x + w3 / (w2 + w3);
539 glDeleteTextures(1, &gltex);
568 glViewport(0, 0, size.width(), size.height());
573 (GLint) size.width(), (GLint) size.height(), 0,
581 glViewport(tmp_viewport.left(), tmp_viewport.top(),
582 tmp_viewport.width(), tmp_viewport.height());
584 bool success =
false;
587 case GL_FRAMEBUFFER_COMPLETE:
588 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
589 QString(
"Created frame buffer object (%1x%2).")
590 .arg(size.width()).arg(size.height()));
593 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
594 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
595 "Frame buffer incomplete_ATTACHMENT");
597 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
598 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
599 "Frame buffer incomplete_MISSING_ATTACHMENT");
601 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
602 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
603 "Frame buffer incomplete_DUPLICATE_ATTACHMENT");
605 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
606 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
607 "Frame buffer incomplete_DIMENSIONS");
609 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
610 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Frame buffer incomplete_FORMATS");
612 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
613 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
614 "Frame buffer incomplete_DRAW_BUFFER");
616 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
617 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
618 "Frame buffer incomplete_READ_BUFFER");
620 case GL_FRAMEBUFFER_UNSUPPORTED:
621 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Frame buffer unsupported.");
624 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
625 QString(
"Unknown frame buffer error %1.").arg(status));
646 QVector<GLuint>::iterator it;
678 glClear(GL_COLOR_BUFFER_BIT);
683 const QRect *
dst,
uint prog,
int alpha,
684 int red,
int green,
int blue)
699 uint target,
const QRectF *
src,
702 if (!textures || !texture_count)
715 const QPen &linePen,
int alpha)
724 const QBrush &fillBrush,
725 const QPen &linePen,
int alpha)
736 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
737 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
738 glDisable(GL_DEPTH_TEST);
739 glDepthMask(GL_FALSE);
740 glDisable(GL_CULL_FACE);
741 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
742 glClear(GL_COLOR_BUFFER_BIT);
748 m_extensions = (
reinterpret_cast<const char *
>(glGetString(GL_EXTENSIONS)));
797 static const QString exts[4] = {
"",
"ARB",
"EXT",
"OES" };
799 for (
int i = 0; i < 4; i++)
801 result =
reinterpret_cast<void*
>(
802 QLibrary::resolve(
"libGLESv2", (proc + exts[i]).toLatin1().
data()));
805 result =
reinterpret_cast<void*
>(getProcAddress(proc + exts[i]));
810 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
811 QString(
"Extension not found: %1").arg(proc));
818 static bool multitexture =
true;
819 static bool vertexarrays =
true;
821 static bool pixelbuffers =
true;
822 static bool vertexbuffers =
true;
823 static bool fences =
true;
824 static bool ycbcrtextures =
true;
825 static bool mipmapping =
true;
826 static bool check =
true;
831 multitexture = !getenv(
"OPENGL_NOMULTITEX");
832 vertexarrays = !getenv(
"OPENGL_NOVERTARRAY");
833 framebuffers = !getenv(
"OPENGL_NOFBO");
834 pixelbuffers = !getenv(
"OPENGL_NOPBO");
835 vertexbuffers = !getenv(
"OPENGL_NOVBO");
836 fences = !getenv(
"OPENGL_NOFENCE");
837 ycbcrtextures = !getenv(
"OPENGL_NOYCBCR");
838 mipmapping = !getenv(
"OPENGL_NOMIPMAP");
840 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling multi-texturing.");
842 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling Vertex Arrays.");
844 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling Framebuffer Objects.");
846 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling Pixel Buffer Objects.");
848 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling Vertex Buffer Objects.");
850 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling fences.");
852 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling YCbCr textures.");
854 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling mipmapping.");
859 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsz);
860 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxunits);
864 m_extensions = (
const char*) glGetString(GL_EXTENSIONS);
876 LOG(VB_GENERAL, LOG_ERR,
LOC +
877 "Insufficient texture units for advanced OpenGL features.");
882 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Multi-texturing not supported. Certain "
883 "OpenGL features will not work");
886 if (
m_extensions.contains(
"GL_EXT_vertex_array") && vertexarrays)
892 LOG(VB_GENERAL, LOG_ERR,
LOC +
893 "GL_EXT_vertex_array extension not supported. This may not work");
896 if (
m_extensions.contains(
"GL_EXT_framebuffer_object") &&
907 && buffer_procs && pixelbuffers)
910 if (
m_extensions.contains(
"GL_ARB_vertex_buffer_object")
911 && buffer_procs && vertexbuffers)
924 if (
m_extensions.contains(
"GL_MESA_ycbcr_texture") && ycbcrtextures)
927 if (
m_extensions.contains(
"GL_APPLE_ycbcr_422") && ycbcrtextures)
930 if (
m_extensions.contains(
"GL_SGIS_generate_mipmap") && mipmapping)
933 static bool debugged =
false;
937 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL vendor : %1")
938 .arg((
const char*) glGetString(GL_VENDOR)));
939 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL renderer: %1")
940 .arg((
const char*) glGetString(GL_RENDERER)));
941 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL version : %1")
942 .arg((
const char*) glGetString(GL_VERSION)));
943 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max texture size: %1 x %2")
945 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max texture units: %1")
947 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Direct rendering: %1")
948 .arg((this->
format().directRendering()) ?
"Yes" :
"No"));
955 LOG(VB_GENERAL, LOG_INFO,
LOC +
"PixelBufferObject support available");
965 m_lock =
new QMutex(QMutex::Recursive);
1044 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Deleting OpenGL Resources");
1065 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
" %1 unexpired vertices")
1071 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
" %1 unexpired VBOs")
1078 QHash<GLuint, MythGLTexture>::iterator it;
1081 glDeleteTextures(1, &(it.key()));
1082 if (it.value().m_data)
1083 delete it.value().m_data;
1084 if (it.value().m_pbo)
1093 QVector<GLuint>::iterator it;
1109 int width = min(src->width(), size.width());
1110 int height = min(src->height(), size.height());
1112 data[0 + TEX_OFFSET] = src->left();
1113 data[1 + TEX_OFFSET] = src->top() + height;
1115 data[6 + TEX_OFFSET] = src->left() +
width;
1116 data[7 + TEX_OFFSET] = src->top();
1120 data[0 + TEX_OFFSET] /= (float)size.width();
1121 data[6 + TEX_OFFSET] /= (float)size.width();
1122 data[1 + TEX_OFFSET] /= (float)size.height();
1123 data[7 + TEX_OFFSET] /= (float)size.height();
1126 data[2 + TEX_OFFSET] = data[0 + TEX_OFFSET];
1127 data[3 + TEX_OFFSET] = data[7 + TEX_OFFSET];
1128 data[4 + TEX_OFFSET] = data[6 + TEX_OFFSET];
1129 data[5 + TEX_OFFSET] = data[1 + TEX_OFFSET];
1131 data[2] = data[0] = dst->left();
1132 data[5] = data[1] = dst->top();
1133 data[4] = data[6] = dst->left() + min(width, dst->width());
1134 data[3] = data[7] = dst->top() + min(height, dst->height());
1147 data[0 + TEX_OFFSET] = src->left();
1148 data[1 + TEX_OFFSET] = src->top() + src->height();
1150 data[6 + TEX_OFFSET] = src->left() + src->width();
1151 data[7 + TEX_OFFSET] = src->top();
1161 data[2 + TEX_OFFSET] = data[0 + TEX_OFFSET];
1162 data[3 + TEX_OFFSET] = data[7 + TEX_OFFSET];
1163 data[4 + TEX_OFFSET] = data[6 + TEX_OFFSET];
1164 data[5 + TEX_OFFSET] = data[1 + TEX_OFFSET];
1166 data[2] = data[0] = dst->left();
1167 data[5] = data[1] = dst->top();
1168 data[4] = data[6] = dst->left() + dst->width();
1169 data[3] = data[7] = dst->top() + dst->height();
1176 uint64_t ref = ((uint64_t)area.left() & 0xfff) +
1177 (((uint64_t)area.top() & 0xfff) << 12) +
1178 (((uint64_t)area.width() & 0xfff) << 24) +
1179 (((uint64_t)area.height() & 0xfff) << 36) +
1180 (((uint64_t)type & 0xfff) << 48);
1189 GLfloat *vertices =
new GLfloat[8];
1191 vertices[2] = vertices[0] = area.left();
1192 vertices[5] = vertices[1] = area.top();
1193 vertices[4] = vertices[6] = area.left() + area.width();
1194 vertices[3] = vertices[7] = area.top() + area.height();
1196 if (type == GL_LINE_LOOP)
1198 vertices[7] = vertices[1];
1199 vertices[5] = vertices[3];
1215 GLfloat *vertices = NULL;
1225 uint64_t ref = ((uint64_t)area.left() & 0xfff) +
1226 (((uint64_t)area.top() & 0xfff) << 12) +
1227 (((uint64_t)area.width() & 0xfff) << 24) +
1228 (((uint64_t)area.height() & 0xfff) << 36) +
1229 (((uint64_t)type & 0xfff) << 48);
1245 void* target =
m_glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
1284 unsigned char *scratch =
new unsigned char[tmp_size];
1289 memset(scratch, 0, tmp_size);
1301 size.width(), size.height(), 0,
m_textures[tex].m_data_fmt,
1314 if (fmt == GL_BGRA || fmt ==GL_RGBA)
1318 else if (fmt == GL_YCBCR_MESA || fmt == GL_YCBCR_422_APPLE ||
1330 case GL_UNSIGNED_BYTE:
1331 bytes =
sizeof(GLubyte);
1333 case GL_UNSIGNED_SHORT_8_8_MESA:
1334 bytes =
sizeof(GLushort);
1337 bytes =
sizeof(GLfloat);
1343 if (!bpp || !bytes || size.width() < 1 || size.height() < 1)
1346 return size.width() * size.height() * bpp * bytes;