Ticket #5324: openglvid_10.diff
File openglvid_10.diff, 32.6 KB (added by , 16 years ago) |
---|
-
libs/libmythtv/openglcontext.cpp
diff -ur -X excl mythtvopengl9/libs/libmythtv/openglcontext.cpp mythtvopengl10/libs/libmythtv/openglcontext.cpp
old new 46 46 vector<GLuint> m_textures; 47 47 vector<GLuint> m_programs; 48 48 vector<GLuint> m_framebuffers; 49 vector<GLuint> m_pbos; 49 50 }; 50 51 51 52 OpenGLContext::OpenGLContext(QMutex *lock) : … … 72 73 DeletePrograms(); 73 74 DeleteTextures(); 74 75 DeleteFrameBuffers(); 76 DeletePBOs(); 75 77 } 76 78 77 79 glFlush(); … … 259 261 ((tex_type) ? kGLExtRect : 0) | 260 262 ((has_gl_fragment_program_support(m_extensions)) ? 261 263 kGLExtFragProg : 0) | 264 ((has_gl_pixelbuffer_object_support(m_extensions)) ? 265 kGLExtPBufObj : 0) | 262 266 ((has_gl_fbuffer_object_support(m_extensions)) ? kGLExtFBufObj : 0) | 263 267 ((minor >= 3) ? kGLXPBuffer : 0); 264 268 … … 723 727 724 728 MakeCurrent(false); 725 729 } 730 731 void OpenGLContext::UpdatePBO(uint tex, uint pbo, 732 const VideoFrame *frame, 733 const unsigned char *alpha) 734 { 735 MakeCurrent(true); 736 737 void *pboMemory; 738 uint tex_size = frame->width * frame->height * 4; 739 740 glBindTexture(GetTextureType(), tex); 741 gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); 742 gMythGLBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 743 tex_size, NULL, GL_STREAM_DRAW); 744 745 pboMemory = gMythGLMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 746 GL_WRITE_ONLY); 747 748 pack_yv12alpha(frame, (unsigned char *)pboMemory, alpha); 749 750 gMythGLUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 751 752 glTexSubImage2D(GetTextureType(), 0, 0, 0, frame->width, frame->height, 753 GL_BGRA, GL_UNSIGNED_BYTE, 0); 754 755 gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 756 757 MakeCurrent(false); 758 } 759 760 761 uint OpenGLContext::CreatePBO(QSize size) 762 { 763 MakeCurrent(true); 764 765 gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 766 glTexImage2D(GetTextureType(), 0, GL_RGBA8, size.width(), size.height(), 767 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); 768 769 GLuint tmp_pbo; 770 gMythGLGenBuffersARB(1, &tmp_pbo); 771 772 gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 773 774 Flush(); 775 776 MakeCurrent(false); 777 778 if (tmp_pbo) 779 m_priv->m_pbos.push_back(tmp_pbo); 780 781 return tmp_pbo; 782 } 783 784 void OpenGLContext::DeletePBO(uint pbo) 785 { 786 MakeCurrent(true); 787 788 vector<GLuint>::iterator it; 789 for (it = m_priv->m_pbos.begin(); 790 it != m_priv->m_pbos.end(); it++) 791 { 792 if (*(it) == pbo) 793 { 794 GLuint glpbo = pbo; 795 gMythGLDeleteBuffersARB(1, &glpbo); 796 m_priv->m_pbos.erase(it); 797 break; 798 } 799 } 800 801 Flush(); 802 803 MakeCurrent(false); 804 } 805 806 void OpenGLContext::DeletePBOs(void) 807 { 808 vector<GLuint>::iterator it; 809 for (it = m_priv->m_pbos.begin(); 810 it != m_priv->m_pbos.end(); it++) 811 { 812 gMythGLDeleteBuffersARB(1, &(*(it))); 813 } 814 m_priv->m_pbos.clear(); 815 816 Flush(); 817 } 818 -
libs/libmythtv/openglcontext.h
diff -ur -X excl mythtvopengl9/libs/libmythtv/openglcontext.h mythtvopengl10/libs/libmythtv/openglcontext.h
old new 11 11 12 12 // MythTV headers 13 13 #include "util-x11.h" 14 #include "frame.h" 14 15 15 16 class OpenGLVideo; 16 17 class PrivateContext; … … 21 22 kGLExtFragProg = 0x02, 22 23 kGLExtFBufObj = 0x04, 23 24 kGLXPBuffer = 0x08, 25 kGLExtPBufObj = 0x10, 24 26 } GLFeatures; 25 27 26 28 class OpenGLContext; … … 77 79 78 80 static bool IsGLXSupported(Display *display, uint major, uint minor); 79 81 82 uint CreatePBO(QSize size); 83 void DeletePBO(uint pbo); 84 void UpdatePBO(uint tex, uint pbo, 85 const VideoFrame *frame, 86 const unsigned char *alpha = NULL); 87 80 88 private: 81 89 void Init2DState(void); 82 90 bool IsGLXSupported(uint major, uint minor) const … … 88 96 void DeleteTextures(void); 89 97 void DeletePrograms(void); 90 98 void DeleteFrameBuffers(void); 99 void DeletePBOs(void); 91 100 92 101 PrivateContext *m_priv; 93 102 … … 142 151 bool IsFeatureSupported(GLFeatures) const { return false; } 143 152 144 153 static bool IsGLXSupported(Display*, uint, uint) { return false; } 154 155 uint CreatePBO(QSize); 156 void DeletePBO(uint); 157 void UpdatePBO(uint, uint, const VideoFrame*, const unsigned char*); 145 158 }; 146 159 147 160 #endif //!USING_OPENGL -
libs/libmythtv/openglvideo.cpp
diff -ur -X excl mythtvopengl9/libs/libmythtv/openglvideo.cpp mythtvopengl10/libs/libmythtv/openglvideo.cpp
old new 44 44 useColourControl(false), viewportControl(false), 45 45 inputTextureSize(0,0), currentFrameNum(0), 46 46 inputUpdated(false), 47 47 fastTexStreaming(false), pixelBufferObject(0), 48 48 convertSize(0,0), convertBuf(NULL), 49 49 50 50 videoResize(false), videoResizeRect(0,0,0,0) … … 62 62 { 63 63 ShutDownYUV2RGB(); 64 64 65 if (pixelBufferObject) 66 gl_context->DeletePBO(pixelBufferObject); 67 pixelBufferObject = 0; 68 65 69 for (uint i = 0; i < inputTextures.size(); i++) 66 70 gl_context->DeleteTexture(inputTextures[i]); 67 71 inputTextures.clear(); … … 114 118 115 119 SetViewPort(display_visible_rect.size()); 116 120 121 fastTexStreaming = gl_context->IsFeatureSupported(kGLExtPBufObj); 122 117 123 if (osd) 118 124 { 119 125 QSize osdsize = display_visible_rect.size(); 120 QSize half_size(osdsize.width() >> 1, osdsize.height() >>1); 121 GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize); 122 GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 123 GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 124 GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize); 125 126 if ((alphatex && ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGBA)) 127 { 128 inputTextures.push_back(ytex); 129 inputTextures.push_back(utex); 130 inputTextures.push_back(vtex); 131 inputTextures.push_back(alphatex); 132 if (!AddFilter(kGLFilterResize)) 126 if (fastTexStreaming) 127 { 128 GLuint tex = CreateVideoTexture(osdsize, inputTextureSize); 129 pixelBufferObject = gl_context->CreatePBO(osdsize); 130 131 if (tex && pixelBufferObject && 132 AddFilter(kGLFilterYUV2RGBA) && 133 AddFilter(kGLFilterResize)) 134 { 135 inputTextures.push_back(tex); 136 } 137 else 138 { 139 Teardown(); 140 fastTexStreaming = false; 141 } 142 } 143 144 if (!fastTexStreaming) 145 { 146 QSize half_size(osdsize.width() >> 1, osdsize.height() >>1); 147 GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize); 148 GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 149 GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 150 GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize); 151 152 if ((alphatex && ytex && utex && vtex) && 153 AddFilter(kGLFilterYUV2RGBA) && 154 AddFilter(kGLFilterResize)) 155 { 156 inputTextures.push_back(ytex); 157 inputTextures.push_back(utex); 158 inputTextures.push_back(vtex); 159 inputTextures.push_back(alphatex); 160 } 161 else 133 162 { 134 163 Teardown(); 135 return false;136 164 } 137 165 } 138 166 } 139 167 else 140 168 { 141 QSize half_size(actual_video_dim.width() >> 1, 142 actual_video_dim.height() >>1); 143 GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 144 GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 145 GLuint ytex = CreateVideoTexture(actual_video_dim, inputTextureSize);; 146 147 if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB)) 148 { 149 inputTextures.push_back(ytex); 150 inputTextures.push_back(utex); 151 inputTextures.push_back(vtex); 169 if (fastTexStreaming) 170 { 171 GLuint tex = CreateVideoTexture(actual_video_dim, inputTextureSize); 172 pixelBufferObject = gl_context->CreatePBO(actual_video_dim); 173 174 if (tex && pixelBufferObject && 175 AddFilter(kGLFilterYUV2RGB)) 176 { 177 inputTextures.push_back(tex); 178 } 179 else 180 { 181 Teardown(); 182 fastTexStreaming = false; 183 } 184 } 185 186 if (!fastTexStreaming) 187 { 188 QSize half_size(actual_video_dim.width() >> 1, actual_video_dim.height() >>1); 189 GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 190 GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 191 GLuint ytex = CreateVideoTexture(actual_video_dim, inputTextureSize); 192 193 if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB)) 194 { 195 inputTextures.push_back(ytex); 196 inputTextures.push_back(utex); 197 inputTextures.push_back(vtex); 198 } 199 else 200 { 201 Teardown(); 202 } 152 203 } 153 204 } 154 205 … … 180 231 } 181 232 } 182 233 234 if (fastTexStreaming) 235 VERBOSE(VB_PLAYBACK, LOC + "Using PBO accelerated texture uploading."); 236 183 237 return true; 184 238 } 185 239 … … 352 406 { 353 407 temp->numInputs = 2; 354 408 } 355 else if ((filter == kGLFilterYUV2RGB ) ||409 else if ((filter == kGLFilterYUV2RGB && !fastTexStreaming) || 356 410 (filter == kGLFilterOneFieldDeintDFR) || 357 411 (filter == kGLFilterKernelDeintDFR) || 358 412 (filter == kGLFilterLinearBlendDeintDFR)) 359 413 { 360 414 temp->numInputs = 3; 361 415 } 362 else if ((filter == kGLFilterYUV2RGBA) )416 else if ((filter == kGLFilterYUV2RGBA) && !fastTexStreaming) 363 417 { 364 418 temp->numInputs = 4; 365 419 } … … 556 610 557 611 if (filters.count(kGLFilterYUV2RGB) && (frame->codec == FMT_YV12)) 558 612 { 559 UpdateInput(frame->buf, frame->offsets, 0, FMT_YV12, actual_video_dim); 613 if (fastTexStreaming && pixelBufferObject) 614 { 615 gl_context->UpdatePBO(inputTextures[0], pixelBufferObject, 616 frame); 617 inputUpdated = true; 618 return; 619 } 620 621 UpdateInput(frame->buf, frame->offsets, FMT_YV12, actual_video_dim); 560 622 return; 561 623 } 562 624 … … 585 647 convertSize.width(), convertSize.height()); 586 648 587 649 int offset = 0; 588 UpdateInput(convertBuf, &offset, 0,FMT_RGB24, convertSize);650 UpdateInput(convertBuf, &offset, FMT_RGB24, convertSize); 589 651 } 590 652 } 591 653 592 654 // locking ok 593 655 void OpenGLVideo::UpdateInput(const unsigned char *buf, const int *offsets, 594 uint texture_index, int format, QSize size) 656 int format, QSize size, 657 const unsigned char *alpha) 595 658 { 596 659 ContextLocker ctx_lock(gl_context); 597 660 598 661 inputUpdated = false; 599 662 600 if (texture_index >= inputTextures.size()) 663 if (fastTexStreaming && pixelBufferObject && 664 FMT_YV12 == format && alpha) 665 { 666 VideoFrame frame; 667 frame.codec = FMT_YV12; 668 frame.buf = (unsigned char *)buf; 669 frame.width = size.width(); 670 frame.height = size.height(); 671 frame.offsets[0] = offsets[0]; 672 frame.offsets[1] = offsets[1]; 673 frame.offsets[2] = offsets[2]; 674 frame.pitches[0] = size.width(); 675 frame.pitches[1] = size.width() >> 1; 676 frame.pitches[2] = size.width() >> 1; 677 gl_context->UpdatePBO(inputTextures[0], pixelBufferObject, 678 &frame, alpha); 679 680 inputUpdated = true; 601 681 return; 682 } 602 683 603 684 copy_pixels_to_texture( 604 685 buf + offsets[0], format, size, 605 inputTextures[ texture_index], gl_context->GetTextureType());686 inputTextures[0], gl_context->GetTextureType()); 606 687 607 688 if (FMT_YV12 == format) 608 689 { 609 690 QSize chroma_size(size.width() >> 1, size.height() >> 1); 610 691 copy_pixels_to_texture( 611 692 buf + offsets[1], format, chroma_size, 612 inputTextures[ texture_index +1],693 inputTextures[1], 613 694 gl_context->GetTextureType()); 614 695 copy_pixels_to_texture( 615 696 buf + offsets[2], format, chroma_size, 616 inputTextures[ texture_index +2],697 inputTextures[2], 617 698 gl_context->GetTextureType()); 699 if (alpha) 700 { 701 copy_pixels_to_texture( 702 alpha, FMT_ALPHA, size, 703 inputTextures[3], 704 gl_context->GetTextureType()); 705 } 618 706 } 619 707 620 708 inputUpdated = true; … … 928 1016 pictureAttribs[kPictureAttribute_Brightness], 929 1017 pictureAttribs[kPictureAttribute_Contrast], 930 1018 pictureAttribs[kPictureAttribute_Colour], 931 0. 0f);1019 0.5f); 932 1020 } 933 1021 break; 934 1022 … … 958 1046 glEnable(GL_BLEND); 959 1047 960 1048 // draw quad 1049 bool multi = ((type == kGLFilterYUV2RGB || 1050 type == kGLFilterYUV2RGBA) && 1051 !fastTexStreaming); 1052 bool multi_alpha = multi && (type == kGLFilterYUV2RGBA); 1053 961 1054 glBegin(GL_QUADS); 962 1055 glTexCoord2f(t_left, t_top); 963 if ( type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)1056 if (multi) 964 1057 { 965 1058 glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_top_uv); 966 1059 glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_top_uv); 967 if ( type == kGLFilterYUV2RGBA)1060 if (multi_alpha) 968 1061 glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_top_uv); 969 1062 } 970 1063 glVertex2f(vleft, vtop); 971 1064 972 1065 glTexCoord2f(t_right, t_top); 973 if ( type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)1066 if (multi) 974 1067 { 975 1068 glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_top_uv); 976 1069 glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_top_uv); 977 if ( type == kGLFilterYUV2RGBA)1070 if (multi_alpha) 978 1071 glMultiTexCoord2f(GL_TEXTURE3, t_right, t_top); 979 1072 } 980 1073 glVertex2f(vright, vtop); 981 1074 982 1075 glTexCoord2f(t_right, t_bottom); 983 if ( type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)1076 if (multi) 984 1077 { 985 1078 glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_bottom_uv); 986 1079 glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_bottom_uv); 987 if ( type == kGLFilterYUV2RGBA)1080 if (multi_alpha) 988 1081 glMultiTexCoord2f(GL_TEXTURE3, t_right, t_bottom); 989 1082 } 990 1083 glVertex2f(vright, vbot); 991 1084 992 1085 glTexCoord2f(t_left, t_bottom); 993 if ( type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)1086 if (multi) 994 1087 { 995 1088 glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_bottom_uv); 996 1089 glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_bottom_uv); 997 if ( type == kGLFilterYUV2RGBA)1090 if (multi_alpha) 998 1091 glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_bottom); 999 1092 } 1000 1093 glVertex2f(vleft, vbot); … … 1151 1244 return ""; 1152 1245 } 1153 1246 1154 static const QString yuv2rgb1a=1247 static const QString init_norm = 1155 1248 "ATTRIB ytex = fragment.texcoord[0];" 1156 1249 "ATTRIB uvtex = fragment.texcoord[1];" 1157 1250 "TEMP res, tmp;"; 1158 1251 1159 static const QString yuv2rgb1b=1252 static const QString init_alpha = 1160 1253 "TEMP alpha;" 1161 1254 "TEX alpha, ytex, texture[3], %1;"; 1162 1255 1163 static const QString yuv2rgb1c=1256 static const QString tex_sample = 1164 1257 "TEX res, ytex, texture[0], %1;" 1165 1258 "TEX tmp.x, uvtex, texture[1], %1;" 1166 1259 "TEX tmp.y, uvtex, texture[2], %1;"; 1167 1260 1168 static const QString yuv2rgb2=1261 static const QString colour_control = 1169 1262 "PARAM adj = program.env[0];" 1170 1263 "SUB res, res, 0.5;" 1171 1264 "MAD res, res, adj.yyyy, adj.xxxx;" 1172 1265 "SUB tmp, tmp, { 0.5, 0.5 };" 1173 1266 "MAD tmp, adj.zzzz, tmp, 0.5;"; 1174 1267 1175 static const QString yuv2rgb3 = 1268 static const QString colour_control_fast = 1269 "PARAM adj = program.env[0];" 1270 "SUB res, res, 0.5;" 1271 "MAD res, res, adj.zzzy, adj.wwwx;"; 1272 1273 static const QString end_norm = 1176 1274 "MAD res, res, 1.164, -0.063;" 1177 1275 "SUB tmp, tmp, { 0.5, 0.5 };" 1178 1276 "MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;" 1179 1277 "MAD result.color, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;"; 1180 1278 1181 static const QString yuv2rgb4=1279 static const QString end_alpha = 1182 1280 "MOV result.color.a, alpha.a;"; 1183 1281 1282 static const QString init_fast = 1283 "ATTRIB tex = fragment.texcoord[0];" 1284 "TEMP tmp, res;" 1285 "TEX res, tex, texture[0], %1;"; 1286 1287 static const QString init_fast_alpha = 1288 "MOV result.color.a, res.g;"; 1289 1290 static const QString end_fast = 1291 "SUB tmp, res.rbgg, { 0.5, 0.5 };" 1292 "MAD res, res.a, 1.164, -0.063;" 1293 "MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;" 1294 "MAD result.color, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;"; 1295 1296 static const QString end_fast_alpha = 1297 "SUB tmp, res.rbgg, { 0.5, 0.5 };" 1298 "MAD res, res.a, 1.164, -0.063;" 1299 "MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;" 1300 "MAD result.color.rgb, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;"; 1301 1184 1302 // locking ok 1185 1303 QString OpenGLVideo::GetProgramString(OpenGLFilterType name) 1186 1304 { … … 1191 1309 switch (name) 1192 1310 { 1193 1311 case kGLFilterYUV2RGB: 1194 ret = ret + yuv2rgb1a + yuv2rgb1c; 1195 if (useColourControl) 1196 ret += yuv2rgb2; 1197 ret += yuv2rgb3; 1312 if (fastTexStreaming) 1313 { 1314 ret += init_fast; 1315 if (useColourControl) 1316 ret += colour_control_fast; 1317 ret += end_fast; 1318 } 1319 else 1320 { 1321 ret = ret + init_norm + tex_sample; 1322 if (useColourControl) 1323 ret += colour_control; 1324 ret += end_norm; 1325 } 1198 1326 break; 1199 1327 1200 1328 case kGLFilterYUV2RGBA: 1201 ret = ret + yuv2rgb1a + yuv2rgb1b + yuv2rgb1c; 1202 if (useColourControl) 1203 ret += yuv2rgb2; 1204 ret = ret + yuv2rgb3 + yuv2rgb4; 1329 if (fastTexStreaming) 1330 { 1331 ret += init_fast + init_fast_alpha; 1332 if (useColourControl) 1333 ret += colour_control_fast; 1334 ret += end_fast_alpha; 1335 } 1336 else 1337 { 1338 ret = ret + init_norm + init_alpha + tex_sample; 1339 if (useColourControl) 1340 ret += colour_control; 1341 ret = ret + end_norm + end_alpha; 1342 } 1205 1343 break; 1206 1344 1207 1345 case kGLFilterKernelDeint: -
libs/libmythtv/openglvideo.h
diff -ur -X excl mythtvopengl9/libs/libmythtv/openglvideo.h mythtvopengl10/libs/libmythtv/openglvideo.h
old new 61 61 62 62 void UpdateInputFrame(const VideoFrame *frame); 63 63 void UpdateInput(const unsigned char *buf, const int *offsets, 64 uint texture_index, int format, QSize size); 64 int format, QSize size, 65 const unsigned char *alpha = NULL); 65 66 66 67 bool AddFilter(const QString &filter) 67 68 { return AddFilter(StringToFilter(filter)); } … … 128 129 glfilt_map_t filters; 129 130 long long currentFrameNum; 130 131 bool inputUpdated; 132 bool fastTexStreaming; 133 uint pixelBufferObject; 131 134 132 135 QSize convertSize; 133 136 unsigned char *convertBuf; … … 151 154 { (void) osd; return false; } 152 155 153 156 void UpdateInputFrame(const VideoFrame*) { } 154 void UpdateInput(const unsigned char*, const int*, uint, int, QSize) { }157 void UpdateInput(const unsigned char*, const int*, int, QSize, unsigned char* = NULL) { } 155 158 156 159 bool AddFilter(const QString&) { return false; } 157 160 bool RemoveFilter(const QString&) { return false; } -
libs/libmythtv/util-opengl.cpp
diff -ur -X excl mythtvopengl9/libs/libmythtv/util-opengl.cpp mythtvopengl10/libs/libmythtv/util-opengl.cpp
old new 3 3 #include "util-opengl.h" 4 4 #include "frame.h" 5 5 6 #ifdef MMX 7 extern "C" { 8 #include "libavcodec/i386/mmx.h" 9 } 10 #endif 11 12 PFNGLMAPBUFFERPROC gMythGLMapBufferARB = NULL; 13 PFNGLBINDBUFFERARBPROC gMythGLBindBufferARB = NULL; 14 PFNGLGENBUFFERSARBPROC gMythGLGenBuffersARB = NULL; 15 PFNGLBUFFERDATAARBPROC gMythGLBufferDataARB = NULL; 16 PFNGLUNMAPBUFFERARBPROC gMythGLUnmapBufferARB = NULL; 17 PFNGLDELETEBUFFERSARBPROC gMythGLDeleteBuffersARB = NULL; 18 6 19 PFNGLGENPROGRAMSARBPROC gMythGLGenProgramsARB = NULL; 7 20 PFNGLBINDPROGRAMARBPROC gMythGLBindProgramARB = NULL; 8 21 PFNGLPROGRAMSTRINGARBPROC gMythGLProgramStringARB = NULL; … … 30 43 31 44 is_initialized = true; 32 45 46 gMythGLMapBufferARB = (PFNGLMAPBUFFERPROC) 47 get_gl_proc_address("glMapBufferARB"); 48 gMythGLBindBufferARB = (PFNGLBINDBUFFERARBPROC) 49 get_gl_proc_address("glBindBufferARB"); 50 gMythGLGenBuffersARB = (PFNGLGENBUFFERSARBPROC) 51 get_gl_proc_address("glGenBuffersARB"); 52 gMythGLBufferDataARB = (PFNGLBUFFERDATAARBPROC) 53 get_gl_proc_address("glBufferDataARB"); 54 gMythGLUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) 55 get_gl_proc_address("glUnmapBufferARB"); 56 gMythGLDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) 57 get_gl_proc_address("glDeleteBuffersARB"); 58 33 59 gMythGLGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) 34 60 get_gl_proc_address("glGenProgramsARB"); 35 61 gMythGLBindProgramARB = (PFNGLBINDPROGRAMARBPROC) … … 369 395 370 396 return gMythGLXGetVideoSyncSGI && gMythGLXWaitVideoSyncSGI; 371 397 } 398 399 bool has_gl_pixelbuffer_object_support(const QString &ext) 400 { 401 init_opengl(); 402 403 if (!ext.contains("GL_EXT_pixel_buffer_object")) 404 return false; 405 406 return (gMythGLMapBufferARB && 407 gMythGLBindBufferARB && 408 gMythGLGenBuffersARB && 409 gMythGLDeleteBuffersARB && 410 gMythGLBufferDataARB && 411 gMythGLUnmapBufferARB); 412 } 413 414 #ifdef MMX 415 static inline void mmx_pack_alpha_high(uint8_t *a1, uint8_t *a2) 416 { 417 movq_m2r (*a1, mm4); 418 punpckhbw_r2r (mm0, mm4); 419 movq_m2r (*a2, mm7); 420 punpckhbw_r2r (mm1, mm7); 421 } 422 423 static inline void mmx_pack_alpha_low(uint8_t *a1, uint8_t *a2) 424 { 425 movq_m2r (*a1, mm4); 426 punpcklbw_r2r (mm0, mm4); 427 movq_m2r (*a2, mm7); 428 punpcklbw_r2r (mm1, mm7); 429 } 430 431 static mmx_t mmx_1s = {0xffffffffffffffffLL}; 432 433 static inline void mmx_pack_alpha1s_high(void) 434 { 435 movq_m2r (mmx_1s, mm4); 436 punpckhbw_r2r (mm0, mm4); 437 movq_m2r (mmx_1s, mm7); 438 punpckhbw_r2r (mm1, mm7); 439 } 440 441 static inline void mmx_pack_alpha1s_low(void) 442 { 443 movq_m2r (mmx_1s, mm4); 444 punpcklbw_r2r (mm0, mm4); 445 movq_m2r (mmx_1s, mm7); 446 punpcklbw_r2r (mm1, mm7); 447 } 448 449 static inline void mmx_pack_start(uint8_t *y1, uint8_t *y2, 450 uint8_t *u, uint8_t *v, 451 uint8_t *dest1, uint8_t *dest2) 452 { 453 movq_m2r (*y1, mm0); 454 movq_m2r (*y2, mm1); 455 movd_m2r (*u, mm2); 456 movd_m2r (*v, mm3); 457 458 punpcklbw_r2r (mm2, mm2); 459 punpcklbw_r2r (mm3, mm3); 460 } 461 462 static inline void mmx_pack_middle(uint8_t *dest1, uint8_t *dest2) 463 { 464 movq_r2r (mm3, mm5); 465 punpcklbw_r2r (mm2, mm5); 466 467 movq_r2r (mm5, mm6); 468 punpcklbw_r2r (mm4, mm6); 469 movq_r2m (mm6, *(dest1)); 470 471 movq_r2r (mm5, mm6); 472 punpckhbw_r2r (mm4, mm6); 473 movq_r2m (mm6, *(dest1 + 8)); 474 475 movq_r2r (mm5, mm6); 476 punpcklbw_r2r (mm7, mm6); 477 movq_r2m (mm6, *(dest2)); 478 479 movq_r2r (mm5, mm6); 480 punpckhbw_r2r (mm7, mm6); 481 movq_r2m (mm6, *(dest2 + 8)); 482 } 483 484 static inline void mmx_pack_end(uint8_t *dest1, uint8_t *dest2) 485 { 486 movq_r2r (mm3, mm5); 487 punpckhbw_r2r (mm2, mm5); 488 489 movq_r2r (mm5, mm6); 490 punpcklbw_r2r (mm4, mm6); 491 movq_r2m (mm6, *(dest1 + 16)); 492 493 movq_r2r (mm5, mm6); 494 punpckhbw_r2r (mm4, mm6); 495 movq_r2m (mm6, *(dest1 + 24)); 496 497 movq_r2r (mm5, mm6); 498 punpcklbw_r2r (mm7, mm6); 499 movq_r2m (mm6, *(dest2 + 16)); 500 501 movq_r2r (mm5, mm6); 502 punpckhbw_r2r (mm7, mm6); 503 movq_r2m (mm6, *(dest2 + 24)); 504 } 505 #endif // MMX 506 507 void pack_yv12alpha(const VideoFrame *frame, 508 const unsigned char *buf, 509 const unsigned char *alpha) 510 { 511 if (frame->codec != FMT_YV12 || (frame->height % 2)) 512 return; 513 514 uint bgra_width = frame->width << 2; 515 uint chroma_width = frame->width >> 1; 516 uint u_extra = frame->pitches[1] - chroma_width; 517 uint v_extra = frame->pitches[2] - chroma_width; 518 519 uint8_t *ypt_1 = (uint8_t *)frame->buf + frame->offsets[0]; 520 uint8_t *ypt_2 = ypt_1 + frame->width; 521 uint8_t *upt = (uint8_t *)frame->buf + frame->offsets[1]; 522 uint8_t *vpt = (uint8_t *)frame->buf + frame->offsets[2]; 523 uint8_t *dst_1 = (uint8_t *) buf; 524 uint8_t *dst_2 = dst_1 + bgra_width; 525 526 if (alpha) 527 { 528 uint8_t *alpha_1 = (uint8_t *) alpha; 529 uint8_t *alpha_2 = alpha_1 + frame->width; 530 531 #ifdef MMX 532 if (!(frame->width % 8)) 533 { 534 for (int row = 0; row < frame->height; row += 2) 535 { 536 for (int col = 0; col < frame->width; col += 8) 537 { 538 mmx_pack_start(ypt_1, ypt_2, upt, vpt, dst_1, dst_2); 539 mmx_pack_alpha_low(alpha_1, alpha_2); 540 mmx_pack_middle(dst_1, dst_2); 541 mmx_pack_alpha_high(alpha_1, alpha_2); 542 mmx_pack_end(dst_1, dst_2); 543 dst_1 += 32; 544 dst_2 += 32; 545 alpha_1 += 8; 546 alpha_2 += 8; 547 ypt_1 += 8; 548 ypt_2 += 8; 549 upt += 4; 550 vpt += 4; 551 } 552 ypt_1 += (frame->pitches[0]); 553 ypt_2 += (frame->pitches[0]); 554 upt += u_extra; 555 vpt += v_extra; 556 dst_1 += bgra_width; 557 dst_2 += bgra_width; 558 alpha_1 += frame->width; 559 alpha_2 += frame->width; 560 } 561 562 emms(); 563 564 return; 565 } 566 #endif //MMX 567 568 for (int row = 0; row < frame->height; row += 2) 569 { 570 for (int col = 0; col < frame->width; col += 2) 571 { 572 *(dst_1++) = *vpt; 573 *(dst_2++) = *vpt; 574 *(dst_1++) = *(alpha_1++); 575 *(dst_2++) = *(alpha_2++); 576 *(dst_1++) = *upt; 577 *(dst_2++) = *upt; 578 *(dst_1++) = *(ypt_1++); 579 *(dst_2++) = *(ypt_2++); 580 581 *(dst_1++) = *vpt; 582 *(dst_2++) = *(vpt++); 583 *(dst_1++) = *(alpha_1++); 584 *(dst_2++) = *(alpha_2++); 585 *(dst_1++) = *upt; 586 *(dst_2++) = *(upt++); 587 *(dst_1++) = *(ypt_1++); 588 *(dst_2++) = *(ypt_2++); 589 } 590 ypt_1 += (frame->pitches[0]); 591 ypt_2 += (frame->pitches[0]); 592 upt += u_extra; 593 vpt += v_extra; 594 alpha_1 += frame->width; 595 alpha_2 += frame->width; 596 dst_1 += bgra_width; 597 dst_2 += bgra_width; 598 } 599 } 600 else 601 { 602 603 #ifdef MMX 604 if (!(frame->width % 8)) 605 { 606 for (int row = 0; row < frame->height; row += 2) 607 { 608 for (int col = 0; col < frame->width; col += 8) 609 { 610 mmx_pack_start(ypt_1, ypt_2, upt, vpt, dst_1, dst_2); 611 mmx_pack_alpha1s_low(); 612 mmx_pack_middle(dst_1, dst_2); 613 mmx_pack_alpha1s_high(); 614 mmx_pack_end(dst_1, dst_2); 615 dst_1 += 32; 616 dst_2 += 32; 617 ypt_1 += 8; 618 ypt_2 += 8; 619 upt += 4; 620 vpt += 4; 621 } 622 ypt_1 += (frame->pitches[0]); 623 ypt_2 += (frame->pitches[0]); 624 upt += u_extra; 625 vpt += v_extra; 626 dst_1 += bgra_width; 627 dst_2 += bgra_width; 628 } 629 630 emms(); 631 632 return; 633 } 634 #endif //MMX 635 636 for (int row = 0; row < frame->height; row += 2) 637 { 638 for (int col = 0; col < frame->width; col += 2) 639 { 640 *(dst_1++) = *vpt; 641 *(dst_2++) = *vpt; 642 *(dst_1++) = 255; 643 *(dst_2++) = 255; 644 *(dst_1++) = *upt; 645 *(dst_2++) = *upt; 646 *(dst_1++) = *(ypt_1++); 647 *(dst_2++) = *(ypt_2++); 648 649 *(dst_1++) = *vpt; 650 *(dst_2++) = *(vpt++); 651 *(dst_1++) = 255; 652 *(dst_2++) = 255; 653 *(dst_1++) = *upt; 654 *(dst_2++) = *(upt++); 655 *(dst_1++) = *(ypt_1++); 656 *(dst_2++) = *(ypt_2++); 657 } 658 ypt_1 += (frame->pitches[0]); 659 ypt_2 += (frame->pitches[0]); 660 upt += u_extra; 661 vpt += v_extra; 662 dst_1 += bgra_width; 663 dst_2 += bgra_width; 664 } 665 } 666 } 667 -
libs/libmythtv/util-opengl.h
diff -ur -X excl mythtvopengl9/libs/libmythtv/util-opengl.h mythtvopengl10/libs/libmythtv/util-opengl.h
old new 8 8 // MythTV headers 9 9 #include "mythcontext.h" 10 10 #include "util-x11.h" 11 #include "frame.h" 11 12 12 13 // GLX headers 13 14 #define GLX_GLXEXT_PROTOTYPES … … 128 129 int texture, 129 130 int texture_type); 130 131 132 void pack_yv12alpha(const VideoFrame *frame, 133 const unsigned char *buf, 134 const unsigned char *alpha = NULL); 135 131 136 __GLXextFuncPtr get_gl_proc_address(const QString &procName); 132 137 133 138 int get_gl_texture_rect_type(const QString &extensions); 134 139 bool has_gl_fbuffer_object_support(const QString &extensions); 135 140 bool has_gl_fragment_program_support(const QString &extensions); 136 141 bool has_glx_video_sync_support(const QString &glx_extensions); 142 bool has_gl_pixelbuffer_object_support(const QString &extensions); 137 143 138 144 extern QString gMythGLExtensions; 139 145 extern uint gMythGLExtSupported; … … 145 151 extern PFNGLDELETEPROGRAMSARBPROC gMythGLDeleteProgramsARB; 146 152 extern PFNGLGETPROGRAMIVARBPROC gMythGLGetProgramivARB; 147 153 154 extern PFNGLMAPBUFFERPROC gMythGLMapBufferARB; 155 extern PFNGLBINDBUFFERARBPROC gMythGLBindBufferARB; 156 extern PFNGLGENBUFFERSARBPROC gMythGLGenBuffersARB; 157 extern PFNGLBUFFERDATAARBPROC gMythGLBufferDataARB; 158 extern PFNGLUNMAPBUFFERARBPROC gMythGLUnmapBufferARB; 159 extern PFNGLDELETEBUFFERSARBPROC gMythGLDeleteBuffersARB; 160 148 161 // Not all platforms with OpenGL that MythTV supports have the 149 162 // GL_EXT_framebuffer_object extension so we need to define these.. 150 163 typedef void (APIENTRYP MYTH_GLGENFRAMEBUFFERSEXTPROC) -
libs/libmythtv/videoout_xv.cpp
diff -ur -X excl mythtvopengl9/libs/libmythtv/videoout_xv.cpp mythtvopengl10/libs/libmythtv/videoout_xv.cpp
old new 4212 4212 surface->v - surface->yuvbuffer, 4213 4213 }; 4214 4214 gl_osdchain->UpdateInput(surface->yuvbuffer, offsets, 4215 0, FMT_YV12, visible); 4216 gl_osdchain->UpdateInput(surface->alpha, offsets, 4217 3, FMT_ALPHA, visible); 4215 FMT_YV12, visible, surface->alpha); 4218 4216 } 4219 4217 return changed; 4220 4218 }