void GraphicsItemRenderer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); DPTR_D(GraphicsItemRenderer); d.painter = painter; { //lock is required only when drawing the frame QMutexLocker locker(&d.img_mutex); Q_UNUSED(locker); //begin paint. how about QPainter::beginNativePainting()? //fill background color when necessary, e.g. renderer is resized, image is null //if we access d.data which will be modified in AVThread, the following must be protected if (d.out_rect != boundingRect() || d.data.isEmpty()) { d.update_background = false; drawBackground(); } //DO NOT return if no data. we should draw other things //NOTE: if data is not copyed in convertData, you should always call drawFrame() if (!d.data.isEmpty()) { drawFrame(); } } //drawXXX only implement the painting, no other logic if (d.draw_osd) drawOSD(); if (d.draw_subtitle) drawSubtitle(); if (d.draw_custom) drawCustom(); //end paint. how about QPainter::endNativePainting()? d.painter = 0; //painter may be not available outside this function }
void Direct2DRenderer::paintEvent(QPaintEvent *) { DPTR_D(Direct2DRenderer); QMutexLocker locker(&d.img_mutex); Q_UNUSED(locker); if (!d.render_target) { qWarning("No render target!!!"); return; } HRESULT hr = S_OK; //begin paint //http://www.daimakuai.net/?page_id=1574 d.render_target->BeginDraw(); //The first bitmap size is 0x0, we should only draw the background //we access d.data which will be modified in AVThread, so must be protected if ((d.update_background && d.out_rect != rect())|| d.data.isEmpty()) { d.update_background = false; drawBackground(); } //d.data is always empty because we did not assign a vaule in convertData? if (!d.data.isEmpty()) { //return; //why the background is white if return? the below code draw an empty bitmap? } drawFrame(); //drawXXX only implement the painting, no other logic if (d.draw_osd) drawOSD(); if (d.draw_subtitle) drawSubtitle(); if (d.draw_custom) drawCustom(); hr = d.render_target->EndDraw(NULL, NULL); if (hr == D2DERR_RECREATE_TARGET) { qDebug("D2DERR_RECREATE_TARGET"); hr = S_OK; d.destroyDeviceResource(); d.createDeviceResource(); //? } //end paint }
void GPHGraphicsManager::internUpdateScreen() { SDL_Surface *srcSurf, *origSurf; int height, width; ScalerProc *scalerProc; int scale1; #if defined(DEBUG) assert(_hwscreen != NULL); assert(_hwscreen->map->sw_data != NULL); #endif // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos || (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { SDL_Rect blackrect = {0, 0, _videoMode.screenWidth *_videoMode.scaleFactor, _newShakePos *_videoMode.scaleFactor}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); _currentShakePos = _newShakePos; _forceFull = true; } // Check whether the palette was changed in the meantime and update the // screen surface accordingly. if (_screen && _paletteDirtyEnd != 0) { SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart); _paletteDirtyEnd = 0; _forceFull = true; } if (!_overlayVisible) { origSurf = _screen; srcSurf = _tmpscreen; width = _videoMode.screenWidth; height = _videoMode.screenHeight; scalerProc = _scalerProc; scale1 = _videoMode.scaleFactor; } else { origSurf = _overlayscreen; srcSurf = _tmpscreen2; width = _videoMode.overlayWidth; height = _videoMode.overlayHeight; scalerProc = Normal1x; scale1 = 1; } // Add the area covered by the mouse cursor to the list of dirty rects if // we have to redraw the mouse. if (_mouseNeedsRedraw) undrawMouse(); #ifdef USE_OSD updateOSD(); #endif // Force a full redraw if requested if (_forceFull) { _numDirtyRects = 1; _dirtyRectList[0].x = 0; _dirtyRectList[0].y = 0; _dirtyRectList[0].w = width; _dirtyRectList[0].h = height; // HACK: Make sure the full hardware screen is wiped clean. SDL_FillRect(_hwscreen, NULL, 0); } // Only draw anything if necessary if (_numDirtyRects > 0 || _mouseNeedsRedraw) { SDL_Rect *r; SDL_Rect dst; uint32 srcPitch, dstPitch; SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects; for (r = _dirtyRectList; r != lastRect; ++r) { dst = *r; dst.x++; // Shift rect by one since 2xSai needs to access the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } SDL_LockSurface(srcSurf); SDL_LockSurface(_hwscreen); srcPitch = srcSurf->pitch; dstPitch = _hwscreen->pitch; for (r = _dirtyRectList; r != lastRect; ++r) { register int dst_y = r->y + _currentShakePos; register int dst_h = 0; register int dst_w = r->w; register int orig_dst_y = 0; register int dst_x = r->x; register int src_y; register int src_x; if (dst_y < height) { dst_h = r->h; if (dst_h > height - dst_y) dst_h = height - dst_y; orig_dst_y = dst_y; src_x = dst_x; src_y = dst_y; if (_videoMode.aspectRatioCorrection && !_overlayVisible) dst_y = real2Aspect(dst_y); assert(scalerProc != NULL); if ((_videoMode.mode == GFX_HALF) && (scalerProc == DownscaleAllByHalf)) { if (dst_x % 2 == 1) { dst_x--; dst_w++; } if (dst_y % 2 == 1) { dst_y--; dst_h++; } src_x = dst_x; src_y = dst_y; dst_x = dst_x / 2; dst_y = dst_y / 2; scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h); } else { scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + r->x * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h); } } if (_videoMode.mode == GFX_HALF && scalerProc == DownscaleAllByHalf) { r->w = r->w / 2; r->h = dst_h / 2; } else { r->w = r->w; r->h = dst_h; } r->x = dst_x; r->y = dst_y; #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); #endif } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. if (_forceFull) { _dirtyRectList[0].y = 0; _dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight() / 2 : effectiveScreenHeight(); } drawMouse(); #ifdef USE_OSD drawOSD(); #endif // Finally, blit all our changes to the screen SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); } _numDirtyRects = 0; _forceFull = false; _mouseNeedsRedraw = false; }