STDMETHODIMP CVRPresenterStreamDXVA::Present(LPBYTE *ppbPlanes, DWORD *pdwStrides, DWORD dwFlags) { LPBYTE pBuf = NULL; DWORD stride = 0; HRESULT hr = S_OK; hr = LockSurface(&pBuf , &stride); if(FAILED(hr)) return hr; DWORD srcWidth[3]; DWORD srcHeight[3]; srcWidth[0] = m_open_param.dwWidth; srcWidth[1] = srcWidth[2] = m_open_param.dwWidth>>1; srcHeight[0] = m_open_param.dwHeight; srcHeight[1] = srcHeight[2] = m_open_param.dwHeight>>1; if(m_open_param.dwFourCC == MAKE_FOURCC('Y','V','1','2')) hr = m_PrepareData.PrepareBufferYV12(pBuf, stride, ppbPlanes, pdwStrides, srcWidth, srcHeight, dwFlags, 0,0,0,m_deinterlace); else if(m_open_param.dwFourCC == MAKE_FOURCC('R','5','6','5')) { } hr = UnlockSurface(); return hr; }
/////////////////// // Precalculate a font's colour void CFont::PreCalculate(const SmartPointer<SDL_Surface> & bmpSurf, Color colour) { Uint32 pixel; int x, y; FillSurface(bmpSurf.get(), SDL_MapRGBA(bmpSurf.get()->format, 255, 0, 255, 0)); // Lock the surfaces LOCK_OR_QUIT(bmpSurf); LOCK_OR_QUIT(bmpFont); Uint8 R, G, B, A; const Uint8 sr = colour.r, sg = colour.g, sb = colour.b; // Outline font: replace white pixels with appropriate color, put black pixels if (OutlineFont) { for (y = 0; y < bmpSurf.get()->h; y++) { for (x = 0; x < bmpSurf.get()->w; x++) { pixel = GetPixel(bmpFont.get(), x, y); GetColour4(pixel, bmpFont.get()->format, &R, &G, &B, &A); if (R == 255 && G == 255 && B == 255) // White PutPixel(bmpSurf.get(), x, y, SDL_MapRGBA(bmpSurf.get()->format, sr, sg, sb, A)); else if (!R && !G && !B) // Black PutPixel(bmpSurf.get(), x, y, SDL_MapRGBA(bmpSurf.get()->format, 0, 0, 0, A)); } } // Not outline: replace black pixels with appropriate color } else { for (y = 0; y < bmpSurf.get()->h; y++) { for (x = 0; x < bmpSurf.get()->w; x++) { pixel = GetPixel(bmpFont.get(), x, y); GetColour4(pixel, bmpFont.get()->format, &R, &G, &B, &A); if (!R && !G && !B) // Black PutPixel(bmpSurf.get(), x, y, SDL_MapRGBA(bmpSurf.get()->format, sr, sg, sb, A)); } } } // Unlock the surfaces UnlockSurface(bmpSurf); UnlockSurface(bmpFont); }
void CPainter::DrawPoint(const CPoint& Point, const CRGBColor& PointColor) { CPoint RealPoint = (m_pWindow != 0) ? Point + m_pWindow->GetClientRect().TopLeft() : Point; if (CRect(0, 0, m_pSurface->w, m_pSurface->h).HitTest(RealPoint) == CRect::RELPOS_INSIDE) { LockSurface(); Uint8* PixelOffset = static_cast<Uint8*>(m_pSurface->pixels) + m_pSurface->format->BytesPerPixel * RealPoint.XPos() + m_pSurface->pitch * RealPoint.YPos(); switch (m_pSurface->format->BytesPerPixel) { case 1: // 8 bpp *reinterpret_cast<Uint8*>(PixelOffset) = static_cast<Uint8>(MixColor(ReadPoint(Point), PointColor).SDLColor(m_pSurface->format)); break; case 2: // 16 bpp *reinterpret_cast<Uint16*>(PixelOffset) = static_cast<Uint16>(MixColor(ReadPoint(Point), PointColor).SDLColor(m_pSurface->format)); break; case 3: // 24 bpp { Uint32 PixelColor = MixColor(ReadPoint(Point), PointColor).SDLColor(m_pSurface->format); Uint8* pPixelSource = reinterpret_cast<Uint8*>(&PixelColor); Uint8* pPixelDest = reinterpret_cast<Uint8*>(PixelOffset); *pPixelDest = *pPixelSource; *(++pPixelDest) = *(++pPixelSource); *(++pPixelDest) = *(++pPixelSource); break; } case 4: // 32 bpp *reinterpret_cast<Uint32*>(PixelOffset) = static_cast<Uint32>(MixColor(ReadPoint(Point), PointColor).SDLColor(m_pSurface->format)); break; default: throw(Wg_Ex_SDL("CPainter::DrawPoint : Unrecognized BytesPerPixel.")); break; } UnlockSurface(); } }
HRESULT STDMETHODCALLTYPE Unlock(LPDIRECTDRAWSURFACE7 surface, LPRECT data) { HRESULT hr; //logOutput << CurrentTimeString() << "Hooked Unlock()" << endl; EnterCriticalSection(&ddrawMutex); //UnlockSurface handles the actual unlocking and un-/rehooks the method (as well as thread synchronisation) hr = UnlockSurface(surface, data); if (getFrontSurface(surface)) { // palette fix, should be tested on several machines if (g_bUsePalette && g_CurrentPalette.bInitialized) //g_CurrentPalette.ReloadPrimarySurfacePaletteEntries(); if (!g_bUseFlipMethod) CaptureDDraw(); } LeaveCriticalSection(&ddrawMutex); return hr; }
/*++ Routine Name: CScanIterator::~CScanIterator Routine Description: CScanIterator destructor Arguments: None Return Value: None --*/ CScanIterator::~CScanIterator() { UnlockSurface(); }
/////////////////// // Calculate character widths, number of characters and offsets void CFont::Parse() { int x; UnicodeChar CurChar = FIRST_CHARACTER; int cur_w; // Lock the surface LOCK_OR_QUIT(bmpFont); Uint32 blue = SDL_MapRGB(bmpFont.get()->format, 0, 0, 255); // a blue pixel always indicates a new char exept for the first uint char_start = 0; for (x = 0; x < bmpFont.get()->w; x++) { // x is always one pixel behind a blue line or x==0 // Ignore any free pixel columns before the character char_start = x; while (x < bmpFont.get()->w && IsColumnFree(x)) ++x; if(x >= bmpFont.get()->w) break; // If we stopped at next blue line/end, this must be a kind of space if (GetPixel(bmpFont.get(), x, 0) == blue || x == bmpFont.get()->w) { cur_w = x - char_start; // Non-blank character } else { char_start = x; ++x; // Read until a blue pixel or end of the image cur_w = 1; while (GetPixel(bmpFont.get(), x, 0) != blue && x < bmpFont.get()->w) { ++x; ++cur_w; } // Ignore any free pixel columns *after* the character uint tmp_x = x - 1; // last line before blue line or end while (IsColumnFree(tmp_x) && cur_w) { --cur_w; --tmp_x; } if(cur_w == 0) warnings << "CFont cur_w == 0" << endl; } // Add the character FontWidth.push_back(cur_w); CharacterOffset.push_back(char_start); NumCharacters++; CurChar++; } // Unlock the surface UnlockSurface(bmpFont); }
/////////////////// // Draw a font (advanced) void CFont::DrawAdv(SDL_Surface * dst, int x, int y, int max_w, Color col, const std::string& txt) { if (txt.size() == 0) return; if(dst == NULL) { errors << "CFont::DrawAdv(" << txt << "): dst == NULL" << endl; return; } if(dst->format == NULL) { errors << "CFont::DrawAdv(" << txt << "): dst->format == NULL" << endl; return; } // Set the newrect width and use this newrect temporarily to draw the font // We use this rect because of precached fonts which use SDL_Blit for drawing (and it takes care of cliprect) SDL_Rect newrect = dst->clip_rect; newrect.w = MIN(newrect.w, (Uint16)max_w); newrect.x = MAX(newrect.x, (Sint16)x); newrect.y = MAX(newrect.y, (Sint16)y); if (!ClipRefRectWith(newrect.x, newrect.y, newrect.w, newrect.h, (SDLRect&)dst->clip_rect)) return; ScopedSurfaceClip clip(dst, newrect); // Look in the precached fonts if there's some for this color SmartPointer<SDL_Surface> bmpCached = NULL; if (Colorize) { // HINT: if we leave this disabled, the drawing will always be done manually // this is a bit (not not much) slower but prevents from the usual errors with CFont (wrong color, invisible, so on) // TODO: should we completly remove the caches? how much speed improvements do they give? // under MacOSX, it doesn't seem to give any performance improvement at all, at least no change in FPS // I have activated it again now as it seem to work at the moment (perhabps because of my change in gfxCreateSurfaceAlpha) if (col == f_white) bmpCached = bmpWhite; else if (col == tLX->clBlack) bmpCached = bmpFont; else if (col == f_green) bmpCached = bmpGreen; } // Not colourize, bmpFont itself should be blitted without any changes, so it's precached else { bmpCached = bmpFont; } // Lock the surfaces // If we use cached font, we do not access the pixels if (!bmpCached.get()) { LOCK_OR_QUIT(dst); LOCK_OR_QUIT(bmpFont); } // Get the color values // TODO: this function should accept a device-independent color, change it asap! Color font_cl(col); // Position at destination surface int char_y = y; int char_h = bmpFont.get()->h; // Get the putpixel & getpixel functors PixelPutAlpha& putter = getPixelAlphaPutFunc(dst); PixelGet& getter = getPixelGetFunc(bmpFont.get()); // Vertical clipping OneSideClip(char_y, char_h, newrect.y, newrect.h); // Get the correct drawing function typedef void(CFont::*GlyphBlitter)(SDL_Surface *dst, const SDL_Rect& r, int sx, int sy, Color col, int glyph_index, PixelPutAlpha& putter, PixelGet& getter); GlyphBlitter func = &CFont::DrawGlyphNormal_Internal; if (OutlineFont) func = &CFont::DrawGlyphOutline_Internal; for (std::string::const_iterator p = txt.begin(); p != txt.end();) { // Line break if (*p == '\n') { y += bmpFont.get()->h + VSpacing; char_y = y; x = newrect.x; p++; // If any further text wouldn't be drawn, just stop if (char_y >= (newrect.y + newrect.h)) break; else { OneSideClip(char_y, char_h, newrect.y, newrect.h); continue; } } // Translate and ignore unknown int l = TranslateCharacter(p, txt.end()); // HINT: increases the iterator if (l == -1) continue; // Check if the current line will be drawn, if not, just proceed if (char_h == 0) continue; // Horizontal clipping int char_x = x; int char_w = FontWidth[l]; if (!OneSideClip(char_x, char_w, newrect.x, newrect.w)) { x += FontWidth[l] + Spacing; continue; } // Precached fonts if (bmpCached.get()) { DrawImageAdv(dst, bmpCached, CharacterOffset[l], 0, x, y, FontWidth[l], bmpFont.get()->h); x += FontWidth[l] + Spacing; continue; } // Draw the glyph (this->*(func))(dst, MakeRect(char_x, char_y, char_w, char_h), char_x - x, char_y - y, font_cl, l, putter, getter); x += FontWidth[l] + Spacing; } // Unlock the surfaces if (!bmpCached.get()) { UnlockSurface(dst); UnlockSurface(bmpFont); } }