예제 #1
0
void f()
{
    time_point t0 = Clock::now();
    m.lock();
    time_point t1 = Clock::now();
    m.lock();
    m.unlock();
    m.unlock();
    ns d = t1 - t0 - ms(250);
    assert(d < ns(2500000));  // within 2.5ms
}
예제 #2
0
// numFrames is number of stereo frames.
// This is called from *outside* the emulator thread.
int __AudioMix(short *outstereo, int numFrames)
{
	// TODO: if mixFrequency != the actual output frequency, resample!

	section.lock();
	int underrun = -1;
	s16 sampleL = 0;
	s16 sampleR = 0;
	bool anythingToPlay = false;
	for (int i = 0; i < numFrames; i++) {
		if (outAudioQueue.size() >= 2)
		{
			sampleL = outAudioQueue.pop_front();
			sampleR = outAudioQueue.pop_front();
			outstereo[i * 2 + 0] = sampleL;
			outstereo[i * 2 + 1] = sampleR;
			anythingToPlay = true;
		} else {
			if (underrun == -1) underrun = i;
			outstereo[i * 2 + 0] = sampleL;  // repeat last sample, can reduce clicking
			outstereo[i * 2 + 1] = sampleR;  // repeat last sample, can reduce clicking
		}
	}
	if (anythingToPlay && underrun >= 0) {
		DEBUG_LOG(HLE, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames);
	} else {
		// DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames);
	}
	section.unlock();
	return underrun >= 0 ? underrun : numFrames;
}
예제 #3
0
void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb)
{
	sMutex.lock();

	delete m_File;
	delete []m_Ram;
	delete []m_ExRam;

	m_File = new FifoDataFile;

	m_Ram = new u8[Memory::RAM_SIZE];
	m_ExRam = new u8[Memory::EXRAM_SIZE];
	memset(m_Ram, 0, Memory::RAM_SIZE);
	memset(m_ExRam, 0, Memory::EXRAM_SIZE);

	m_File->SetIsWii(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii);

	if (!m_IsRecording)
	{
		m_WasRecording = false;
		m_IsRecording = true;
		m_RecordFramesRemaining = numFrames;
	}

	m_RequestedRecordingEnd = false;
	m_FinishedCb = finishedCb;

	sMutex.unlock();
}
예제 #4
0
void __AudioDoState(PointerWrap &p)
{
	section.lock();

	p.Do(eventAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventAudioUpdate, "AudioUpdate", &hleAudioUpdate);
	p.Do(eventHostAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventHostAudioUpdate, "AudioUpdateHost", &hleHostAudioUpdate);

	p.Do(mixFrequency);
	outAudioQueue.DoState(p);

	int chanCount = ARRAY_SIZE(chans);
	p.Do(chanCount);
	if (chanCount != ARRAY_SIZE(chans))
	{
		ERROR_LOG(HLE, "Savestate failure: different number of audio channels.");
		section.unlock();
		return;
	}
	for (int i = 0; i < chanCount; ++i)
		chans[i].DoState(p);

	section.unlock();
	p.DoMarker("sceAudio");
}
예제 #5
0
u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking)
{
	u32 ret = 0;
	section.lock();
	if (chan.sampleAddress == 0)
		return SCE_ERROR_AUDIO_NOT_OUTPUT;
	if (chan.sampleQueue.size() > chan.sampleCount*2*chanQueueMaxSizeFactor) {
		// Block!
		if (blocking) {
			chan.waitingThread = __KernelGetCurThread();
			// WARNING: This changes currentThread so must grab waitingThread before (line above).
			__KernelWaitCurThread(WAITTYPE_AUDIOCHANNEL, (SceUID)chanNum, 0, 0, false, "blocking audio waited");
			// Fall through to the sample queueing, don't want to lose the samples even though
			// we're getting full.
		}
		else
		{
			chan.waitingThread = 0;
			return SCE_ERROR_AUDIO_CHANNEL_BUSY;
		}
	}
	if (chan.format == PSP_AUDIO_FORMAT_STEREO)
	{
		const u32 totalSamples = chan.sampleCount * 2;

		if (IS_LITTLE_ENDIAN)
		{
			s16 *sampleData = (s16 *) Memory::GetPointer(chan.sampleAddress);

			// Walking a pointer for speed.  But let's make sure we wouldn't trip on an invalid ptr.
			if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16)))
			{
				for (u32 i = 0; i < totalSamples; i++)
					chan.sampleQueue.push(*sampleData++);
			}
		}
		else
		{
			for (u32 i = 0; i < totalSamples; i++)
				chan.sampleQueue.push((s16)Memory::Read_U16(chan.sampleAddress + sizeof(s16) * i));
		}

		ret = chan.sampleCount;
	}
	else if (chan.format == PSP_AUDIO_FORMAT_MONO)
	{
		for (u32 i = 0; i < chan.sampleCount; i++)
		{
			// Expand to stereo
			s16 sample = (s16)Memory::Read_U16(chan.sampleAddress + 2 * i);
			chan.sampleQueue.push(sample);
			chan.sampleQueue.push(sample);
		}

		ret = chan.sampleCount;
	}
	section.unlock();
	return ret;
}
예제 #6
0
int main()
{
    m.lock();
    std::thread t(f);
    std::this_thread::sleep_for(ms(250));
    m.unlock();
    t.join();
}
예제 #7
0
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate()
{
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.

	s32 mixBuffer[hwBlockSize * 2];
	memset(mixBuffer, 0, sizeof(mixBuffer));

	for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX; i++)
	{
		if (!chans[i].reserved)
			continue;
		if (!chans[i].sampleQueue.size()) {
			// ERROR_LOG(HLE, "No queued samples, skipping channel %i", i);
			continue;
		}

		for (int s = 0; s < hwBlockSize; s++)
		{
			if (chans[i].sampleQueue.size() >= 2)
			{
				s16 sampleL = chans[i].sampleQueue.pop_front();
				s16 sampleR = chans[i].sampleQueue.pop_front();
				mixBuffer[s * 2 + 0] += sampleL;
				mixBuffer[s * 2 + 1] += sampleR;
			} 
			else
			{
				ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize);
				break;
			}
		}

		if (chans[i].sampleQueue.size() < chans[i].sampleCount * 2 * chanQueueMinSizeFactor)
		{
			// Ask the thread to send more samples until next time, queue is being drained.
			if (chans[i].waitingThread) {
				SceUID waitingThread = chans[i].waitingThread;
				chans[i].waitingThread = 0;
				// DEBUG_LOG(HLE, "Woke thread %i for some buffer filling", waitingThread);
				__KernelResumeThreadFromWait(waitingThread, chans[i].sampleCount);
			}
		}
	}

	if (g_Config.bEnableSound) {
		section.lock();
		if (outAudioQueue.room() >= hwBlockSize * 2) {
			// Push the mixed samples onto the output audio queue.
			for (int i = 0; i < hwBlockSize; i++) {
				s32 sampleL = mixBuffer[i * 2 + 0] >> 2;  // TODO - what factor?
				s32 sampleR = mixBuffer[i * 2 + 1] >> 2;

				outAudioQueue.push((s16)sampleL);
				outAudioQueue.push((s16)sampleR);
			}
		} else {
예제 #8
0
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate()
{
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.

	s32 mixBuffer[hwBlockSize * 2];
	memset(mixBuffer, 0, sizeof(mixBuffer));

	for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
	{
		if (!chans[i].reserved)
			continue;
		__AudioWakeThreads(chans[i], hwBlockSize);

		if (!chans[i].sampleQueue.size()) {
			// ERROR_LOG(HLE, "No queued samples, skipping channel %i", i);
			continue;
		}

		for (int s = 0; s < hwBlockSize; s++)
		{
			if (chans[i].sampleQueue.size() >= 2)
			{
				s16 sampleL = chans[i].sampleQueue.pop_front();
				s16 sampleR = chans[i].sampleQueue.pop_front();
				mixBuffer[s * 2 + 0] += sampleL;
				mixBuffer[s * 2 + 1] += sampleR;
			} 
			else
			{
				ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize);
				break;
			}
		}
	}

	if (g_Config.bEnableSound) {
		section.lock();
		if (outAudioQueue.room() >= hwBlockSize * 2) {
			// Push the mixed samples onto the output audio queue.
			for (int i = 0; i < hwBlockSize; i++) {
				s16 sampleL = clamp_s16(mixBuffer[i * 2 + 0]);
				s16 sampleR = clamp_s16(mixBuffer[i * 2 + 1]);

				outAudioQueue.push((s16)sampleL);
				outAudioQueue.push((s16)sampleR);
			}
		} else {
			// This happens quite a lot. There's still something slightly off
			// about the amount of audio we produce.
			DEBUG_LOG(HLE, "Audio outbuffer overrun! room = %i / %i", outAudioQueue.room(), (u32)outAudioQueue.capacity());
		}
		section.unlock();
	}
	
}
예제 #9
0
void FifoPlayerDlg::RecordingFinished()
{
	sMutex.lock();

	if (m_EvtHandler)
	{
		wxCommandEvent event(RECORDING_FINISHED_EVENT);
		m_EvtHandler->AddPendingEvent(event);
	}

	sMutex.unlock();
}
예제 #10
0
void FifoPlayerDlg::FileLoaded()
{
	sMutex.lock();

	if (m_EvtHandler)
	{
		wxPaintEvent event;
		m_EvtHandler->AddPendingEvent(event);
	}

	sMutex.unlock();
}
예제 #11
0
void FifoPlayerDlg::FrameWritten()
{
	sMutex.lock();

	if (m_EvtHandler)
	{
		wxCommandEvent event(FRAME_WRITTEN_EVENT);
		m_EvtHandler->AddPendingEvent(event);
	}

	sMutex.unlock();
}
예제 #12
0
FifoPlayerDlg::FifoPlayerDlg(wxWindow * const parent) :
	wxDialog(parent, wxID_ANY, _("FIFO Player"), wxDefaultPosition, wxDefaultSize),
	m_FramesToRecord(1)
{
	CreateGUIControls();

	sMutex.lock();	
	m_EvtHandler = GetEventHandler();	
	sMutex.unlock();

	FifoPlayer::GetInstance().SetFileLoadedCallback(FileLoaded);
	FifoPlayer::GetInstance().SetFrameWrittenCallback(FrameWritten);
}
예제 #13
0
void attemp_10k_increasesR() {
	int i;
	mrtx.lock();
	mrtx.lock(); // 递归锁,多次调用lock都不会死锁
	for (i=0; i<10; ++i) {
		++counter;
		std::this_thread::sleep_for(std::chrono::microseconds(1*1000000));
		std::cout << "thread Reverse[" << std::this_thread::get_id() <<"]" << "add the counter" << endl; 

	}

	mrtx.unlock();
}
예제 #14
0
void FifoRecorder::EndFrame(u32 fifoStart, u32 fifoEnd)
{
	// m_IsRecording is assumed to be true at this point, otherwise this function would not be called

	sMutex.lock();

	m_FrameEnded = true;

	m_CurrentFrame.fifoStart = fifoStart;
	m_CurrentFrame.fifoEnd = fifoEnd;

	if (m_WasRecording)
	{
		// If recording a fixed number of frames then check if the end of the recording was reached
		if (m_RecordFramesRemaining > 0)
		{
			--m_RecordFramesRemaining;
			if (m_RecordFramesRemaining == 0)
				m_RequestedRecordingEnd = true;
		}
	}
	else
	{
		m_WasRecording = true;

		// Skip the first data which will be the frame copy command
		m_SkipNextData = true;
		m_SkipFutureData = false;

		m_FrameEnded = false;

		m_FifoData.reserve(1024 * 1024 * 4);
		m_FifoData.clear();
	}

	if (m_RequestedRecordingEnd)
	{
		// Skip data after the next time WriteFifoData is called
		m_SkipFutureData = true;
		// Signal video backend that it should not call this function when the next frame ends
		m_IsRecording = false;
	}

	sMutex.unlock();
}
예제 #15
0
void FifoRecorder::SetVideoMemory(u32 *bpMem, u32 *cpMem, u32 *xfMem, u32 *xfRegs, u32 xfRegsSize)
{
	sMutex.lock();

	if (m_File)
	{
		memcpy(m_File->GetBPMem(), bpMem, FifoDataFile::BP_MEM_SIZE * 4);
		memcpy(m_File->GetCPMem(), cpMem, FifoDataFile::CP_MEM_SIZE * 4);
		memcpy(m_File->GetXFMem(), xfMem, FifoDataFile::XF_MEM_SIZE * 4);

		u32 xfRegsCopySize = std::min((u32)FifoDataFile::XF_REGS_SIZE, xfRegsSize);
		memcpy(m_File->GetXFRegs(), xfRegs, xfRegsCopySize * 4);
	}

	m_RecordAnalyzer.Initialize(bpMem, cpMem);

	sMutex.unlock();
}
예제 #16
0
static int AVCodecMTLockCallback(void** mutex, AVLockOp op)
{
	switch (op)
	{
	case AV_LOCK_CREATE:
		*mutex = &kAVCodecMTLock;
		break;
	case AV_LOCK_OBTAIN:
		kAVCodecMTLock.lock();
		break;
	case AV_LOCK_RELEASE:
		kAVCodecMTLock.unlock();
		break;
	case AV_LOCK_DESTROY:
		*mutex = NULL;
		break;
	}
	return 0;
}
예제 #17
0
FifoPlayerDlg::~FifoPlayerDlg()
{
	Disconnect(RECORDING_FINISHED_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnRecordingFinished), NULL, this);
	Disconnect(FRAME_WRITTEN_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnFrameWritten), NULL, this);

	// Disconnect Events
	Disconnect(wxEVT_PAINT, wxPaintEventHandler(FifoPlayerDlg::OnPaint), NULL, this);
	m_FrameFromCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnFrameFrom), NULL, this);
	m_FrameToCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnFrameTo), NULL, this);
	m_ObjectFromCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnObjectFrom), NULL, this);
	m_ObjectToCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnObjectTo), NULL, this);
	m_EarlyMemoryUpdates->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnCheckEarlyMemoryUpdates), NULL, this);
	m_RecordStop->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnRecordStop), NULL, this);
	m_Save->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnSaveFile), NULL, this);	
	m_FramesToRecordCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnNumFramesToRecord), NULL, this);
	m_Close->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnCloseClick), NULL, this);

	FifoPlayer::GetInstance().SetFrameWrittenCallback(NULL);

	sMutex.lock();	
	m_EvtHandler = NULL;
	sMutex.unlock();
}
예제 #18
0
void FifoRecorder::WriteGPCommand(const u8 *data, u32 size)
{
	if (!m_SkipNextData)
	{
		m_RecordAnalyzer.AnalyzeGPCommand(data);

		// Copy data to buffer
		size_t currentSize = m_FifoData.size();
		m_FifoData.resize(currentSize + size);
		memcpy(&m_FifoData[currentSize], data, size);
	}

	if (m_FrameEnded && m_FifoData.size() > 0)
	{
		size_t dataSize = m_FifoData.size();
		m_CurrentFrame.fifoDataSize = (u32)dataSize;
		m_CurrentFrame.fifoData = new u8[dataSize];
		memcpy(m_CurrentFrame.fifoData, m_FifoData.data(), dataSize);

		sMutex.lock();

		// Copy frame to file
		// The file will be responsible for freeing the memory allocated for each frame's fifoData
		m_File->AddFrame(m_CurrentFrame);

		if (m_FinishedCb && m_RequestedRecordingEnd)
			m_FinishedCb();

		sMutex.unlock();

		m_CurrentFrame.memoryUpdates.clear();
		m_FifoData.clear();
		m_FrameEnded = false;
	}

	m_SkipNextData = m_SkipFutureData;
}
예제 #19
0
void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb)
{
	sMutex.lock();

	delete m_File;

	m_File = new FifoDataFile;
	std::fill(m_Ram.begin(), m_Ram.end(), 0);
	std::fill(m_ExRam.begin(), m_ExRam.end(), 0);

	m_File->SetIsWii(SConfig::GetInstance().bWii);

	if (!m_IsRecording)
	{
		m_WasRecording = false;
		m_IsRecording = true;
		m_RecordFramesRemaining = numFrames;
	}

	m_RequestedRecordingEnd = false;
	m_FinishedCb = finishedCb;

	sMutex.unlock();
}
LongRunningOperation::LongRunningOperation()
{
	_operationMutex.lock();
}
예제 #21
0
void StartBulkLog(){
  log_mutex.lock();
  add_timestamp = false;
}
예제 #22
0
// We will inject the stereo here 
void sys_glAttachShader(GLuint program, GLuint shader)
{
	m_opengl32Mutex.lock();

	orig_glCompileShader = (func_glCompileShader)orig_wglGetProcAddress("glCompileShader");
	if (orig_glCompileShader == 0x0)
		add_log("glCompileShader not found !!!!");
	orig_glGetShaderiv = (func_glGetShaderiv_t)orig_wglGetProcAddress("glGetShaderiv");
	if (orig_glGetShaderiv == 0x0)
		add_log("glGetShaderiv not found !!!!");

	// Add the CRC of the program
	std::string programSring = std::to_string(program);
	DWORD progCRC32 = crc32buf(programSring.c_str(), programSring.length());
	
	// Get the correct shader type
	// Get the instance
	ShaderManager *shaderManager = ShaderManager::getInstance();
	
	// Depends on what type of shader it is we do stuff
	if (shaderManager->isShaderType(shader, GL_VERTEX_SHADER))
	{
		//get the original shader Source
		std::string shaderSource = shaderManager->getShaderSource(shader);

		// Calculate the CRC32 before we do any injection
		// Otherwise the CRC32 will change
		DWORD crc32 = crc32buf(shaderSource.c_str(), shaderSource.length());
		crc32 += progCRC32;

		if (shaderManager->GetVertexInjectionState())
		{
			//Apply the custom shaders
			// If we failed apply normal injection
			if (shaderManager->ApplyExceptionShaders(shaderSource, GL_VERTEX_SHADER, crc32) == false)
			{
				//Insert Stereo
				shaderSource = shaderManager->injectStereoScopy(shaderSource, program);
			}
		}

		// Swap the Source
		shaderManager->applyShaderSource(shader, shaderSource, NULL);

		// Store it as an existing shader
		EXISTING_SHADER_T currentShader;
		currentShader.m_CRC32 = crc32;
		currentShader.m_programId = program;
		currentShader.m_shaderId = shader;
		currentShader.m_shaderSourceCode = shaderSource;
		currentShader.m_shaderType = GL_VERTEX_SHADER;
		// Push it back
		shaderManager->addExistingShaderInfo(currentShader);
		
		// Export the Source
		ExportShader("Vertex", currentShader.m_programId, currentShader.m_CRC32, currentShader.m_shaderSourceCode);

		// We also need to compile the shader before attaching it
		//Compile shader
		(*orig_glCompileShader)(shader);

		//Test compile
		GLint statusOk = 0;
		(*orig_glGetShaderiv)(shader, GL_COMPILE_STATUS, &statusOk);

		if (statusOk == GL_FALSE)
		{
			CheckCompileState(shader);
		}
	}
	else if (shaderManager->isShaderType(shader, GL_FRAGMENT_SHADER))
	{
		//get the original shader Source
		std::string shaderSource = shaderManager->getShaderSource(shader);

		// Calculate the CRC32
		DWORD crc32 = crc32buf(shaderSource.c_str(), shaderSource.length());
		crc32 += progCRC32;

		if (shaderManager->GetVertexInjectionState())
		{
			//Apply the custom shaders
			// If we failed apply normal injection
			if (shaderManager->ApplyExceptionShaders(shaderSource, GL_FRAGMENT_SHADER, crc32) == false)
			{
				// This only happens in development mode.
#ifdef DEBUG_WRAPPER
				//Insert Stereo
				shaderSource = shaderManager->injectFragmentModification(shaderSource, program);
#endif
			}
		}

		// Swap the Source
		shaderManager->applyShaderSource(shader, shaderSource, NULL);

		// Store it as an existing shader
		EXISTING_SHADER_T currentShader;
		currentShader.m_CRC32 = crc32;
		currentShader.m_programId = program;
		currentShader.m_shaderId = shader;
		currentShader.m_shaderSourceCode = shaderSource;
		currentShader.m_shaderType = GL_FRAGMENT_SHADER;
		// Push it back
		shaderManager->addExistingShaderInfo(currentShader);

		// Export the Source
		ExportShader("Pixel", currentShader.m_programId, currentShader.m_CRC32, currentShader.m_shaderSourceCode);

		//Compile shader
		(*orig_glCompileShader)(shader);

		// We also need to compile the shader before attaching it
		//Test compile
		GLint statusOk = 0;
		(*orig_glGetShaderiv)(shader, GL_COMPILE_STATUS, &statusOk);

		if (statusOk == GL_FALSE)
		{
			CheckCompileState(shader);
		}
	}
	
	// We attach after we swapped the sources
	(*orig_glAttachShader)(program, shader);

	m_opengl32Mutex.unlock();
}
예제 #23
0
// add the stereo values
void sys_glUseProgram(GLuint program)
{
	m_opengl32Mutex.lock();

	// Get the shaderManager
	ShaderManager * shaderManager = ShaderManager::getInstance();

#ifdef DEBUG_WRAPPER
	if (shaderManager->GetVertexInjectionState())
	{
		shaderManager->ApplyDebugExceptionShaders();
	}
#endif

	// Use the original program
	(*orig_glUseProgram)(program);

	if (shaderManager->GetVertexInjectionState())
	{
		// Get the locations of the uniforms
		GLfloat value;
		const GLchar *uniform_eye = (GLchar*)"g_eye";
		const GLchar *uniform_eye_spearation = (GLchar*)"g_eye_separation";
		const GLchar *uniform_convergence = (GLchar*)"g_convergence";
		const GLchar *uniform_vertexEnabled = (GLchar*)"g_vertexEnabled";
		const GLchar *uniform_pixelEnabled = (GLchar*)"g_pixelEnabled";


		// Get our functions from the driver. Be sure to only take them once
		if (orig_glGetUniformLocation == NULL)
		{
			orig_glGetUniformLocation = (func_glGetUniformLocation_t)(orig_wglGetProcAddress)("glGetUniformLocation");
		}
		//glUniform1f
		if (orig_glUniform1f == NULL)
		{

			orig_glUniform1f = (func_glUniform1f_t)(orig_wglGetProcAddress)("glUniform1f");
		}

		if ((GLint)program >= 0)
		{
			GLint location_eye = (*orig_glGetUniformLocation)(program, uniform_eye);
			GLint location_eye_separation = (*orig_glGetUniformLocation)(program, uniform_eye_spearation);
			GLint location_convergence = (*orig_glGetUniformLocation)(program, uniform_convergence);
			GLint location_vertexEnabled = (*orig_glGetUniformLocation)(program, uniform_vertexEnabled);
			GLint location_pixelEnabled = (*orig_glGetUniformLocation)(program, uniform_pixelEnabled);

			//set the uniform inside the shaders
			if (NV3DVisionGetCurrentFrame() == 1)
			{
				//left eye
				value = -1.0f;
				(*orig_glUniform1f)(location_eye, value);
			}
			else
			{
				//right eye
				value = +1.0f;
				(*orig_glUniform1f)(location_eye, value);
			}
			//Set the Separation and convergence
			(*orig_glUniform1f)(location_eye_separation, Get3DEyeSeparation());
			(*orig_glUniform1f)(location_convergence, Get3DConvergence());
			(*orig_glUniform1f)(location_vertexEnabled, 1.0f);
			(*orig_glUniform1f)(location_pixelEnabled, 1.0f);
		}

		/////////////////////////////////////
		// APPLY CUSTOM SHADER PARAMS
		/////////////////////////////////////
		shaderManager->ApplyCustomShaderParams(program);
		
		/////////////////////////////////////
		// USED TO DISABLE ALOT OF SHADERS
		/////////////////////////////////////
#ifdef	DEBUG_WRAPPER
		if (shaderManager->VertexShadersExceptionsEnabled())
		{
			if (((GLint)program >= (GLint)shaderManager->GetExceptionShaderStart() && (GLint)program <= (GLint)shaderManager->GetExceptionShaderEnd()))
			{
				GLint location_eye_separation = (*orig_glGetUniformLocation)(program, uniform_eye_spearation);
				GLint location_convergence = (*orig_glGetUniformLocation)(program, uniform_convergence);

				//Set the Separation and convergence
				(*orig_glUniform1f)(location_eye_separation, 0);
				(*orig_glUniform1f)(location_convergence, 0);

				// Do we disable the vertex shaders ???
				if (shaderManager->VertexShaderExceptionsDisableShader())
				{
					GLint location_enabled = (*orig_glGetUniformLocation)(program, uniform_vertexEnabled);
					(*orig_glUniform1f)(location_enabled, 0.0f);
				}
				else
				{
					GLint location_enabled = (*orig_glGetUniformLocation)(program, uniform_vertexEnabled);
					(*orig_glUniform1f)(location_enabled, 1.0f);
				}
			}
			if (shaderManager->DisableCurrentShader())
			{
				// If we are navigating vertexes
				if (isCurrentShaderVertex)
				{
					// Disable the current Shader
					if (debugVertexIndex == (int)program)
					{
						GLint location_enabled = (*orig_glGetUniformLocation)(program, uniform_vertexEnabled);
						(*orig_glUniform1f)(location_enabled, 0.0f);
					}
				}
				else // Pixel Shader
				{
					// Disable the current Shader
					if (debugPixelIndex == (int)program)
					{
						GLint location_enabled = (*orig_glGetUniformLocation)(program, uniform_pixelEnabled);
						(*orig_glUniform1f)(location_enabled, 0.0f);
					}
				}
			}
		}
#endif	
	}

	m_opengl32Mutex.unlock();
}
예제 #24
0
파일: MemMap.cpp 프로젝트: Orphis/ppsspp
// Wanting to avoid include pollution, MemMap.h is included a lot.
MemoryInitedLock::MemoryInitedLock()
{
	g_shutdownLock.lock();
}