예제 #1
0
void DebugStats()
{
	gpu->UpdateStats();
	char stats[2048];

	sprintf(stats,
		"Frames: %i\n"
		"DL processing time: %0.2f ms\n"
		"Kernel processing time: %0.2f ms\n"
		"Slowest syscall: %s : %0.2f ms\n"
		"Most active syscall: %s : %0.2f ms\n"
		"Draw calls: %i, flushes %i\n"
		"Cached Draw calls: %i\n"
		"Num Tracked Vertex Arrays: %i\n"
		"Vertices Submitted: %i\n"
		"Cached Vertices Drawn: %i\n"
		"Uncached Vertices Drawn: %i\n"
		"FBOs active: %i\n"
		"Textures active: %i, decoded: %i\n"
		"Texture invalidations: %i\n"
		"Vertex shaders loaded: %i\n"
		"Fragment shaders loaded: %i\n"
		"Combined shaders loaded: %i\n",
		gpuStats.numFrames,
		gpuStats.msProcessingDisplayLists * 1000.0f,
		kernelStats.msInSyscalls * 1000.0f,
		kernelStats.slowestSyscallName ? kernelStats.slowestSyscallName : "(none)",
		kernelStats.slowestSyscallTime * 1000.0f,
		kernelStats.summedSlowestSyscallName ? kernelStats.summedSlowestSyscallName : "(none)",
		kernelStats.summedSlowestSyscallTime * 1000.0f,
		gpuStats.numDrawCalls,
		gpuStats.numFlushes,
		gpuStats.numCachedDrawCalls,
		gpuStats.numTrackedVertexArrays,
		gpuStats.numVertsSubmitted,
		gpuStats.numCachedVertsDrawn,
		gpuStats.numUncachedVertsDrawn,
		gpuStats.numFBOs,
		gpuStats.numTextures,
		gpuStats.numTexturesDecoded,
		gpuStats.numTextureInvalidations,
		gpuStats.numVertexShaders,
		gpuStats.numFragmentShaders,
		gpuStats.numShaders
		);

	float zoom = 0.3f; /// g_Config.iWindowZoom;
	float soff = 0.3f;
	PPGeBegin();
	PPGeDrawText(stats, soff, soff, 0, zoom, 0xCC000000);
	PPGeDrawText(stats, -soff, -soff, 0, zoom, 0xCC000000);
	PPGeDrawText(stats, 0, 0, 0, zoom, 0xFFFFFFFF);
	PPGeEnd();

	gpuStats.resetFrame();
	kernelStats.ResetFrame();
}
예제 #2
0
void CalculateFPS()
{
	static double highestFps = 0.0;
	static int lastFpsFrame = 0;
	static double lastFpsTime = 0.0;
	static double fps = 0.0;

	time_update();
	double now = time_now_d();

	if (now >= lastFpsTime + 1.0)
	{
		fps = (gpuStats.numFrames - lastFpsFrame) / (now - lastFpsTime);
		if (fps > highestFps)
			highestFps = fps;

		lastFpsFrame = gpuStats.numFrames;	
		lastFpsTime = now;
	}

	char stats[50];
	sprintf(stats, "VPS: %0.1f", fps);

	#ifdef USING_GLES2
		float zoom = 0.7f; /// g_Config.iWindowZoom;
		float soff = 0.7f;
	#else
		float zoom = 0.5f; /// g_Config.iWindowZoom;
		float soff = 0.5f;
	#endif
	PPGeBegin();
	PPGeDrawText(stats, 476 + soff, 4 + soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
	PPGeDrawText(stats, 476 + -soff, 4 -soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
	PPGeDrawText(stats, 476, 4, PPGE_ALIGN_RIGHT, zoom, 0xFF30FF30);
	PPGeEnd();
}
예제 #3
0
파일: PSPDialog.cpp 프로젝트: Almamu/ppsspp
void PSPDialog::EndDraw()
{
	PPGeEnd();
}
예제 #4
0
void hleEnterVblank(u64 userdata, int cyclesLate) {
	int vbCount = userdata;

	DEBUG_LOG(HLE, "Enter VBlank %i", vbCount);

	isVblank = 1;

	// Fire the vblank listeners before we wake threads.
	__DisplayFireVblank();

	// Wake up threads waiting for VBlank
	for (size_t i = 0; i < vblankWaitingThreads.size(); i++) {
		if (--vblankWaitingThreads[i].vcountUnblock == 0) {
			__KernelResumeThreadFromWait(vblankWaitingThreads[i].threadID, 0);
			vblankWaitingThreads.erase(vblankWaitingThreads.begin() + i--);
		}
	}

	// Trigger VBlank interrupt handlers.
	__TriggerInterrupt(PSP_INTR_IMMEDIATE | PSP_INTR_ONLY_IF_ENABLED | PSP_INTR_ALWAYS_RESCHED, PSP_VBLANK_INTR, PSP_INTR_SUB_ALL);

	CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount + 1);

	// TODO: Should this be done here or in hleLeaveVblank?
	if (framebufIsLatched) {
		DEBUG_LOG(HLE, "Setting latched framebuffer %08x (prev: %08x)", latchedFramebuf.topaddr, framebuf.topaddr);
		framebuf = latchedFramebuf;
		framebufIsLatched = false;
		gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.pspFramebufLinesize, framebuf.pspFramebufFormat);
	}

	gpuStats.numFrames++;

	// Now we can subvert the Ge engine in order to draw custom overlays like stat counters etc.
	if (g_Config.bShowDebugStats && gpuStats.numDrawCalls) {
		DebugStats();
	}

	if (g_Config.bShowFPSCounter) {
		char stats[50];

		sprintf(stats, "%0.1f", calculateFPS());

		#ifdef USING_GLES2
			float zoom = 0.7f; /// g_Config.iWindowZoom;
			float soff = 0.7f;
		#else
			float zoom = 0.5f; /// g_Config.iWindowZoom;
			float soff = 0.5f;
		#endif
		PPGeBegin();
		PPGeDrawText(stats, 476 + soff, 4 + soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
		PPGeDrawText(stats, 476 + -soff, 4 -soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
		PPGeDrawText(stats, 476, 4, PPGE_ALIGN_RIGHT, zoom, 0xFF30FF30);
		PPGeEnd();
	}

	// Draw screen overlays before blitting. Saves and restores the Ge context.
	// Yeah, this has to be the right moment to end the frame. Give the graphics backend opportunity
	// to blit the framebuffer, in order to support half-framerate games that otherwise wouldn't have
	// anything to draw here.
	gstate_c.skipDrawReason &= ~SKIPDRAW_SKIPFRAME;

	bool throttle, skipFrame, skipFlip;
	
	DoFrameTiming(throttle, skipFrame, skipFlip);

	// Setting CORE_NEXTFRAME causes a swap.
	if (skipFrame) {
		gstate_c.skipDrawReason |= SKIPDRAW_SKIPFRAME;
		numSkippedFrames++;
	} else {
		numSkippedFrames = 0;
	}

	if (!skipFlip) {
		// Might've just quit / been paused.
		if (coreState == CORE_RUNNING) {
			coreState = CORE_NEXTFRAME;
		}
		CoreTiming::ScheduleEvent(0 - cyclesLate, afterFlipEvent, 0);

		gpu->CopyDisplayToOutput();
	}

	// Returning here with coreState == CORE_NEXTFRAME causes a buffer flip to happen (next frame).
	// Right after, we regain control for a little bit in hleAfterFlip. I think that's a great
	// place to do housekeeping.
}
예제 #5
0
void hleEnterVblank(u64 userdata, int cyclesLate) {
	int vbCount = userdata;

	DEBUG_LOG(HLE, "Enter VBlank %i", vbCount);

	isVblank = 1;

	// Fire the vblank listeners before we wake threads.
	__DisplayFireVblank();

	// Wake up threads waiting for VBlank
	for (size_t i = 0; i < vblankWaitingThreads.size(); i++) {
		if (--vblankWaitingThreads[i].vcountUnblock == 0) {
			__KernelResumeThreadFromWait(vblankWaitingThreads[i].threadID, 0);
			vblankWaitingThreads.erase(vblankWaitingThreads.begin() + i--);
		}
	}

	// Trigger VBlank interrupt handlers.
	__TriggerInterrupt(PSP_INTR_IMMEDIATE | PSP_INTR_ONLY_IF_ENABLED | PSP_INTR_ALWAYS_RESCHED, PSP_VBLANK_INTR, PSP_INTR_SUB_ALL);

	CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount+1);

	// TODO: Should this be done here or in hleLeaveVblank?
	if (framebufIsLatched) {
		DEBUG_LOG(HLE, "Setting latched framebuffer %08x (prev: %08x)", latchedFramebuf.topaddr, framebuf.topaddr);
		framebuf = latchedFramebuf;
		framebufIsLatched = false;
		gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.pspFramebufLinesize, framebuf.pspFramebufFormat);
	}

	// Draw screen overlays before blitting. Saves and restores the Ge context.
	gpuStats.numFrames++;

	// Now we can subvert the Ge engine in order to draw custom overlays like stat counters etc.
	if (g_Config.bShowDebugStats && gpuStats.numDrawCalls) {
		gpu->UpdateStats();
		char stats[2048];
		
		sprintf(stats,
			"Frames: %i\n"
			"DL processing time: %0.2f ms\n"
			"Kernel processing time: %0.2f ms\n"
			"Slowest syscall: %s : %0.2f ms\n"
			"Most active syscall: %s : %0.2f ms\n"
			"Draw calls: %i, flushes %i\n"
			"Cached Draw calls: %i\n"
			"Num Tracked Vertex Arrays: %i\n"
			"Vertices Submitted: %i\n"
			"Cached Vertices Drawn: %i\n"
			"Uncached Vertices Drawn: %i\n"
			"FBOs active: %i\n"
			"Textures active: %i, decoded: %i\n"
			"Texture invalidations: %i\n"
			"Vertex shaders loaded: %i\n"
			"Fragment shaders loaded: %i\n"
			"Combined shaders loaded: %i\n",
			gpuStats.numFrames,
			gpuStats.msProcessingDisplayLists * 1000.0f,
			kernelStats.msInSyscalls * 1000.0f,
			kernelStats.slowestSyscallName ? kernelStats.slowestSyscallName : "(none)",
			kernelStats.slowestSyscallTime * 1000.0f,
			kernelStats.summedSlowestSyscallName ? kernelStats.summedSlowestSyscallName : "(none)",
			kernelStats.summedSlowestSyscallTime * 1000.0f,
			gpuStats.numDrawCalls,
			gpuStats.numFlushes,
			gpuStats.numCachedDrawCalls,
			gpuStats.numTrackedVertexArrays,
			gpuStats.numVertsSubmitted,
			gpuStats.numCachedVertsDrawn,
			gpuStats.numUncachedVertsDrawn,
			gpuStats.numFBOs,
			gpuStats.numTextures,
			gpuStats.numTexturesDecoded,
			gpuStats.numTextureInvalidations,
			gpuStats.numVertexShaders,
			gpuStats.numFragmentShaders,
			gpuStats.numShaders
			);

		float zoom = 0.3f; /// g_Config.iWindowZoom;
		float soff = 0.3f;
		PPGeBegin();
		PPGeDrawText(stats, soff, soff, 0, zoom, 0xCC000000);
		PPGeDrawText(stats, -soff, -soff, 0, zoom, 0xCC000000);
		PPGeDrawText(stats, 0, 0, 0, zoom, 0xFFFFFFFF);
		PPGeEnd();

		gpuStats.resetFrame();
		kernelStats.ResetFrame();
	}

	if (g_Config.bShowFPSCounter) {
		char stats[50];

		sprintf(stats, "%0.1f", calculateFPS());

		#ifdef USING_GLES2
			float zoom = 0.7f; /// g_Config.iWindowZoom;
			float soff = 0.7f;
		#else
			float zoom = 0.5f; /// g_Config.iWindowZoom;
			float soff = 0.5f;
		#endif
		PPGeBegin();
		PPGeDrawText(stats, 476 + soff, 4 + soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
		PPGeDrawText(stats, 476 + -soff, 4 -soff, PPGE_ALIGN_RIGHT, zoom, 0xCC000000);
		PPGeDrawText(stats, 476, 4, PPGE_ALIGN_RIGHT, zoom, 0xFF30FF30);
		PPGeEnd();
	}

	// Yeah, this has to be the right moment to end the frame. Give the graphics backend opportunity
	// to blit the framebuffer, in order to support half-framerate games that otherwise wouldn't have
	// anything to draw here.
	gpu->CopyDisplayToOutput();

	host->EndFrame();

#ifdef _WIN32
	// Best place to throttle the frame rate on non vsynced platforms is probably here. Let's try it.
	time_update();
	if (lastFrameTime == 0.0)
		lastFrameTime = time_now_d();
	if (!GetAsyncKeyState(VK_TAB) && !PSP_CoreParameter().headLess) {
		while (time_now_d() < lastFrameTime + 1.0 / 60.0) {
			Common::SleepCurrentThread(1);
			time_update();
		}
		// Advance lastFrameTime by a constant amount each frame,
		// but don't let it get too far behind.
		lastFrameTime = std::max(lastFrameTime + 1.0 / 60.0, time_now_d() - 1.5 / 60.0);
	}

	// We are going to have to do something about audio timing for platforms that
	// are vsynced to something that's not exactly 60fps..

#endif

	host->BeginFrame();
	gpu->BeginFrame();

	// Tell the emu core that it's time to stop emulating
	// Win32 doesn't need this.
#ifndef _WIN32
	coreState = CORE_NEXTFRAME;
#endif
}
예제 #6
0
void hleEnterVblank(u64 userdata, int cyclesLate) {
	int vbCount = userdata;

	DEBUG_LOG(HLE, "Enter VBlank %i", vbCount);

	isVblank = 1;

	// Fire the vblank listeners before we wake threads.
	__DisplayFireVblank();

	// Wake up threads waiting for VBlank
	for (size_t i = 0; i < vblankWaitingThreads.size(); i++) {
		__KernelResumeThreadFromWait(vblankWaitingThreads[i].threadID, 0);
	}
	vblankWaitingThreads.clear();

	// Trigger VBlank interrupt handlers.
	__TriggerInterrupt(PSP_INTR_IMMEDIATE | PSP_INTR_ONLY_IF_ENABLED, PSP_VBLANK_INTR);

	CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount+1);

	// TODO: Should this be done here or in hleLeaveVblank?
	if (framebufIsLatched) {
		DEBUG_LOG(HLE, "Setting latched framebuffer %08x (prev: %08x)", latchedFramebuf.topaddr, framebuf.topaddr);
		framebuf = latchedFramebuf;
		framebufIsLatched = false;
		gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.pspFramebufLinesize, framebuf.pspFramebufFormat);
	}

	// Draw screen overlays before blitting. Saves and restores the Ge context.

	gpuStats.numFrames++;

	// Yeah, this has to be the right moment to end the frame. Give the graphics backend opportunity
	// to blit the framebuffer, in order to support half-framerate games that otherwise wouldn't have
	// anything to draw here.
	gpu->CopyDisplayToOutput();

	// Now we can subvert the Ge engine in order to draw custom overlays like stat counters etc.
	// Here we will be drawing to the non buffered front surface.
	if (g_Config.bShowDebugStats && gpuStats.numDrawCalls) {
		gpu->UpdateStats();
		char stats[512];
		sprintf(stats,
			"Frames: %i\n"
			"Draw calls: %i\n"
			"Draw flushes: %i\n"
			"Vertices Transformed: %i\n"
			"Textures active: %i\n"
			"Textures decoded: %i\n"
			"Vertex shaders loaded: %i\n"
			"Fragment shaders loaded: %i\n"
			"Combined shaders loaded: %i\n",
			gpuStats.numFrames,
			gpuStats.numDrawCalls,
			gpuStats.numFlushes,
			gpuStats.numVertsTransformed,
			gpuStats.numTextures,
			gpuStats.numTexturesDecoded,
			gpuStats.numVertexShaders,
			gpuStats.numFragmentShaders,
			gpuStats.numShaders
			);

		float zoom = 0.7f; /// g_Config.iWindowZoom;
		PPGeBegin();
		PPGeDrawText(stats, 0, 0, 0, zoom, 0xFFc0c0c0);
		PPGeEnd();

		gpuStats.resetFrame();
	}

	host->EndFrame();

#ifdef _WIN32
	static double lastFrameTime = 0.0;
	// Best place to throttle the frame rate on non vsynced platforms is probably here. Let's try it.
	time_update();
	if (lastFrameTime == 0.0)
		lastFrameTime = time_now_d();
	if (!GetAsyncKeyState(VK_TAB)) {
		while (time_now_d() < lastFrameTime + 1.0 / 60.0) {
			Common::SleepCurrentThread(1);
			time_update();
		}
		// Advance lastFrameTime by a constant amount each frame,
		// but don't let it get too far behind.
		lastFrameTime = std::max(lastFrameTime + 1.0 / 60.0, time_now_d() - 1.5 / 60.0);
	}

	// We are going to have to do something about audio timing for platforms that
	// are vsynced to something that's not exactly 60fps..

#endif

	host->BeginFrame();
	gpu->BeginFrame();

	// Tell the emu core that it's time to stop emulating
	// Win32 doesn't need this.
#ifndef _WIN32
	coreState = CORE_NEXTFRAME;
#endif
}