2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
\r
3 Portions copyright 2008 Jon Gettler
\r
5 This file is part of VOMP.
\r
7 VOMP is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 VOMP is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with VOMP; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
22 #include "surfacedirectfb.h"
\r
28 #include "osddirectfb.h"
\r
32 SurfaceDirectFB::SurfaceDirectFB(int id)
\r
38 SurfaceDirectFB::~SurfaceDirectFB()
\r
40 if (surface) surface->Release(surface);
\r
44 int SurfaceDirectFB::create(UINT width, UINT height)
\r
47 while (!Osd::getInstance()->isInitted() && counter<2000) {
\r
48 MILLISLEEP(50); //Wait for Grafiksystem initialization
\r
51 if (!Osd::getInstance()->isInitted()) return -1;
\r
53 IDirectFB*dfb=((OsdDirectFB*)Osd::getInstance())->getDfb();
\r
54 printf("ich bin doof");fflush(stdout);
\r
55 if (screen == this)
\r
57 IDirectFBDisplayLayer *osd_layer=((OsdDirectFB*)Osd::getInstance())->getOsdLayer();
\r
58 if (osd_layer->GetSurface(osd_layer,&surface)!=DFB_OK)
\r
63 surface->Clear(surface,0x0,0x0,0x0,0xFF);
\r
65 DFBSurfaceDescription dsc;
\r
66 memset(&dsc,0,sizeof(dsc));
\r
67 *((int*)&dsc.flags)=DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
\r
71 dsc.caps= DSCAPS_NONE;
\r
72 if (dfb->CreateSurface(dfb,&dsc,&surface)!=DFB_OK)
\r
80 void SurfaceDirectFB::display()
\r
82 // unsigned long fb_descriptor[2];
\r
84 fb_descriptor[0] = surface.sfc.handle;
\r
85 fb_descriptor[1] = 1;
\r
87 // ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor);
\r
91 // ----------------------------------------------------------------------------
\r
93 // Now for the drawing functions
\r
96 int SurfaceDirectFB::fillblt(int x, int y, int width, int height, unsigned int c)
\r
99 unsigned char r,g,b,a;
\r
105 surface->GetSize(surface,&sw,&sh);
\r
107 if (nx >sw) nx=sw-1;
\r
108 if (ny >sh) ny=sh-1;
\r
110 if ((nx+nw) >= sw) nw=sw-nx;
\r
111 if ((ny+nh) >= sh) nh=sh-ny;
\r
113 if ((nx<0) || (ny < 0) || (nh <=0) || (nw <=0)) {
\r
117 a= (c &0xff000000)>>24;
\r
118 r= (c &0x00ff0000)>>16;
\r
119 g= (c &0x0000ff00)>>8;
\r
120 b= (c &0x000000ff);
\r
123 surface->SetColor(surface,r,g,b,a);
\r
124 surface->FillRectangle(surface,nx,ny,nw,nh);
\r
128 void SurfaceDirectFB::drawPixel(int x, int y, unsigned int c, bool fastdraw)
\r
131 unsigned char r,g,b,a;
\r
135 surface->GetSize(surface,&sw,&sh);
\r
141 a= (c &0xff000000)>>24;
\r
142 r= (c &0x00ff0000)>>16;
\r
143 g= (c &0x0000ff00)>>8;
\r
144 b= (c &0x000000ff);
\r
147 if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {
\r
148 offset= y* pitch+x*4;
\r
153 surface->Unlock(surface);
\r
158 void SurfaceDirectFB::drawPixel(int x, int y, Colour& c, bool fastdraw)
\r
164 surface->GetSize(surface,&sw,&sh);
\r
169 if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {
\r
170 offset= y* pitch+x*4;
\r
171 dst[offset++]=c.blue;
\r
172 dst[offset++]=c.green;
\r
173 dst[offset++]=c.red;
\r
174 dst[offset]=c.alpha;
\r
175 surface->Unlock(surface);
\r
180 void SurfaceDirectFB::drawHorzLine(int x1, int x2, int y, unsigned int c)
\r
182 fillblt(x1, y, x2-x1, 1, c);
\r
185 void SurfaceDirectFB::drawVertLine(int x, int y1, int y2, unsigned int c)
\r
187 fillblt(x, y1, 1, y2-y1, c);
\r
190 void SurfaceDirectFB::drawBitmap(int x, int y, const Bitmap& bm)
\r
192 UINT bmw = bm.getWidth(); UINT bmh = bm.getHeight();
\r
193 if (bmw == 0 || bmh == 0) return;
\r
194 if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height)) return;
\r
195 int remainder = (surface.sfc.width % 4);
\r
197 if (remainder == 0)
\r
198 line = surface.sfc.width;
\r
200 line = surface.sfc.width + (4 - remainder);
\r
201 const std::vector<UCHAR>& bmdata = bm.rawData();
\r
202 const std::vector<UCHAR>& Y = bm.palette.getYVector();
\r
203 const std::vector<UCHAR>& Cr = bm.palette.getCrVector();
\r
204 const std::vector<UCHAR>& Cb = bm.palette.getCbVector();
\r
205 const std::vector<UCHAR>& A = bm.palette.getAVector();
\r
207 UINT s_offset = x + y*line;
\r
208 UINT plotWidth = bmw;
\r
209 UINT plotHeight = bmh;
\r
210 if (x + plotWidth - 1 > surface.sfc.width)
\r
211 plotWidth = surface.sfc.width - x + 1;
\r
212 if (y + plotHeight - 1 > surface.sfc.height)
\r
213 plotHeight = surface.sfc.height - y + 1;
\r
214 for (UINT j = 0; j < plotHeight; ++j)
\r
217 if (x & 1) // odd x - need to plot first column separately
\r
219 UCHAR index = bmdata[b_offset];
\r
220 *(surface.base[0] + s_offset) = Y[index];
\r
221 *(surface.base[1] + s_offset - 1) = Cb[index];
\r
222 *(surface.base[1] + s_offset) = Cr[index];
\r
223 *(surface.base[2] + s_offset) = A[index];
\r
226 // Now, plot pairs of pixels with averaged chroma values
\r
227 while (i < plotWidth - 1)
\r
229 UCHAR index1 = bmdata[b_offset + i];
\r
230 UCHAR index2 = bmdata[b_offset + i + 1];
\r
231 *(surface.base[0] + s_offset + i) = Y[index1];
\r
232 *(surface.base[0] + s_offset + i + 1) = Y[index2];
\r
233 *(surface.base[1] + s_offset + i) = (Cb[index1] + Cb[index2]) / 2;
\r
234 *(surface.base[1] + s_offset + i + 1) = (Cr[index1] + Cr[index2]) / 2;
\r
235 *(surface.base[2] + s_offset + i) = A[index1];
\r
236 *(surface.base[2] + s_offset + i + 1) = A[index2];
\r
239 if (i == plotWidth - 1) // One column left to do
\r
241 UCHAR index = bmdata[b_offset + i];
\r
242 *(surface.base[0] + s_offset + i) = Y[index];
\r
243 *(surface.base[1] + s_offset + i) = Cb[index];
\r
244 *(surface.base[1] + s_offset + i + 1) = Cr[index];
\r
245 *(surface.base[2] + s_offset + i) = A[index];
\r
252 /* surface update to screen needs:
\r
253 source x distance into this surface
\r
254 source y distance into this surface
\r
257 destination x on screen
\r
258 destination y on screen
\r
260 int SurfaceDirectFB::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
\r
262 IDirectFBSurface* screensurf=((SurfaceDirectFB*)screen)->getSurfaceDFB();
\r
263 if (!screensurf) return 0;
\r
264 if (this==screen) return 0;
\r
269 screensurf->GetSize(screensurf,&sw,&sh);
\r
270 // screensurf->Clear(screensurf,0x0,0x0,0x0,0xFF);
\r
276 DFBRectangle drect; //TODO make osd HD
\r
282 // screensurf->Blit(screensurf,surface,&rect,dx,dy);
\r
283 screensurf->StretchBlit(screensurf,surface,&rect,&drect);
\r
285 return 0;//blt(fdOsd, surface.sfc.handle, sx, sy, w, h, ((SurfaceDirectFB*)screen)->getSurfaceHandle(), dx, dy);
\r
288 int SurfaceDirectFB::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
\r
289 {//Skip it, noone uses this!
\r
294 void SurfaceDirectFB::screenShot(const char* fileName)
\r
300 void SurfaceDirectFB::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
\r