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