2 Copyright 2006 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
22 #include "surfaceopengl.h"
23 #include "osdopengl.h"
28 inline unsigned int InternalColour(unsigned int c){
29 return (c &0x000000FF)<<16 |
35 SurfaceOpenGL::SurfaceOpenGL(int id)
45 SurfaceOpenGL::~SurfaceOpenGL()
52 glDeleteTextures(1,&gltexture);
57 int SurfaceOpenGL::create(UINT width, UINT height)
59 OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));
60 //osd->BeginPainting();
63 if (this == screen) { // We do not need locking here, since the osd calls this
67 glGenTextures(1, &gltexture);
69 glBindTexture(GL_TEXTURE_2D, gltexture);
71 void *image = malloc(sheight * swidth * 4);
72 memset(image, 0, sheight * swidth * 4);
73 /* for (int i=0;i< sheight * swidth * 4; i++) { //fill it with garbage, useful for debugging
74 ((char*)image)[i]=i%255;
76 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, swidth, sheight, 0, GL_RGBA,
77 GL_UNSIGNED_BYTE, image);
82 data=(char*)malloc(sizeof(uint32_t)*width*height);
91 void SurfaceOpenGL::display()
95 int SurfaceOpenGL::fillblt(int x, int y, int width, int height, const DrawStyle& c) {
97 //since this might be called before surface
98 //allocation we will wait in this case, hopefully without deadlocks
99 if (screen == this || !data ) {
100 //This should not happen!
105 /* OsdWin* osd=((OsdWin*)(Osd::getInstance()));
107 osd->BeginPainting();
109 glViewport(0,0,swidth,sheight);*/
111 //osd->EndPainting();
114 unsigned int my_c=InternalColour(c.rgba());
117 if (height+y>sheight) iheight=sheight-y;
119 if (width+x>swidth) iwidth=swidth-y;
123 for (line = y; line < (iheight + y); line++) {
124 uint32_t *row = ((unsigned int*) (((char*) data) + (swidth * line + x)
125 * sizeof(uint32_t)));
126 for (column = 0; column < iwidth; column++) {
131 /* if (d3dsurface->UnlockRect() != D3D_OK) {
135 osd->EndPainting();*/
141 void SurfaceOpenGL::startFastDraw(){
145 void SurfaceOpenGL::endFastDraw(){
149 void SurfaceOpenGL::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
150 int c = ( (0xFF000000 )
152 | (colour.green << 8)
155 drawPixel(x, y, c, fastdraw);
158 void SurfaceOpenGL::drawPixel(int x, int y, unsigned int c, bool fastdraw) {
159 //FixMe: locking for every single Pixel will be painfully slow
160 if (screen == this) {
161 //This should not happen!
165 return; //why does this happen
169 srf_mutex.lock(); //since this might be called before surface
171 //allocation we will wait in this case, hopefully without deadlocks
173 //osd = ((OsdWin*) (Osd::getInstance()));
175 if (x >= swidth || y >= sheight)
176 return; //do not draw outside the surface
178 unsigned int my_c=InternalColour(c);
180 unsigned int*row = (unsigned int*) (((char*) data + (swidth * y + x)
181 * sizeof(uint32_t)));
185 srf_mutex.unlock(); //since this might be called before surface
190 void SurfaceOpenGL::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
192 fillblt(x1, y, x2-x1, 1, c);
195 void SurfaceOpenGL::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
197 fillblt(x, y1, 1, y2-y1, c);
200 void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region) //region should not matter for SD
202 // Temporary code? Draw one pixel at a time using drawPixel()
204 for (UINT j = 0; j < bm.getHeight(); ++j)
205 for (UINT i = 0; i < bm.getWidth(); ++i)
206 drawPixel(x+i, y+j, bm.getColour(i,j),true);
210 int SurfaceOpenGL::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
212 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark1");
213 srf_mutex.lock();//since this might be called before surface
214 //allocation we will wait in this case, hopefully without deadlocks
216 OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));
217 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark2");
218 GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture();
220 osd->BeginPainting();
221 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3");
222 glBindTexture(GL_TEXTURE_2D, screengltexture);
223 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError());
225 for (int y=0;y<h;y++) { //hopefully this is not too slow
226 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4a %d %d %d %d %d %d",sx,sy,w,h,dx,dy);
227 glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE,
228 data+((y+sy)*swidth+sx)*sizeof(uint32_t));
240 int SurfaceOpenGL::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
242 //I don't see code using this function, so I skip it, since it is a MVP specific interface
246 void SurfaceOpenGL::screenShot(const char* fileName)
248 //Isn't this for debugging only, so I won't implement it yet
251 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
253 //Isn't this for debugging only, so I won't implement it yet
257 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
259 WaitForSingleObject(event,INFINITE); //since this might be called before surface
260 //allocation we will wait in this case, hopefully without deadlocks
262 return ; //why does this happen
264 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
267 D3DXIMAGE_INFO image_inf;
268 osd->BeginPainting();
269 // D3DXGetImageInfoFromFile(fileName,&image_inf);
270 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
271 RECT dest_rec={x,y,x+image_inf.Width,
273 /* if (D3DXLoadSurfaceFromFile(
281 &image_inf)!=D3D_OK) {
282 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
285 if (D3DXLoadSurfaceFromResource(
294 &image_inf)!=D3D_OK) {
295 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
299 *width=image_inf.Width;
300 *height=image_inf.Height;
305 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
306 WaitForSingleObject(event,INFINITE); //since this might be called before surface
307 //allocation we will wait in this case, hopefully without deadlocks
309 return ; //why does this happen
311 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
314 D3DXIMAGE_INFO image_inf;
315 osd->BeginPainting();
316 // D3DXGetImageInfoFromFile(fileName,&image_inf);
317 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
318 RECT dest_rec={x,y,x+image_inf.Width,
320 /* if (D3DXLoadSurfaceFromFile(
328 &image_inf)!=D3D_OK) {
329 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
332 /* if (D3DXLoadSurfaceFromResource(
341 &image_inf)!=D3D_OK) {
342 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
345 if (D3DXLoadSurfaceFromFileInMemory(
354 &image_inf)!=D3D_OK) {
355 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
359 *width=image_inf.Width;
360 *height=image_inf.Height;