Ejemplo n.º 1
0
static void autoclock_frame(arcan_frameserver* tgt)
{
	if (!tgt->clock.left)
		return;

	if (!tgt->clock.frametime)
		tgt->clock.frametime = arcan_frametime();

	int64_t delta = arcan_frametime() - tgt->clock.frametime;
	if (delta < 0){

	}
	else if (delta == 0)
		return;

	if (tgt->clock.left <= delta){
		tgt->clock.left = tgt->clock.start;
		tgt->clock.frametime = arcan_frametime();
		arcan_event ev = {
			.category = EVENT_TARGET,
			.tgt.kind = TARGET_COMMAND_STEPFRAME,
			.tgt.ioevs[0].iv = delta / tgt->clock.start,
			.tgt.ioevs[1].iv = 1
		};
		arcan_frameserver_pushevent(tgt, &ev);
	}
	else
Ejemplo n.º 2
0
Archivo: video.c Proyecto: mewbak/arcan
void platform_video_synch(uint64_t tick_count, float fract,
	video_synchevent pre, video_synchevent post)
{
	long long start = arcan_timemillis();
	if (pre)
		pre();

	arcan_vobject* vobj = arcan_video_getobject(out_vid);
	if (!vobj){
		out_vid = ARCAN_VIDEO_WORLDID;
		vobj = arcan_video_getobject(ARCAN_VIDEO_WORLDID);
	}

	size_t nd;
	arcan_bench_register_cost( arcan_vint_refresh(fract, &nd) );
	agp_shader_id shid = agp_default_shader(BASIC_2D);

	agp_activate_rendertarget(NULL);
	if (blackframes){
		agp_rendertarget_clear();
		blackframes--;
	}

	if (vobj->program > 0)
		shid = vobj->program;

	agp_activate_vstore(out_vid == ARCAN_VIDEO_WORLDID ?
		arcan_vint_world() : vobj->vstore);

	agp_shader_activate(shid);

	agp_draw_vobj(0, 0, d_width, d_height, txcos, NULL);
	arcan_vint_drawcursor(false);

/*
 * NOTE: heuristic fix-point for direct- mapping dedicated source for
 * low latency here when we fix up internal syncing paths.
 */
	eglSwapBuffers(eglDpy, eglSurface);

/* With dynamic, we run an artificial vsync if the time between swaps
 * become to low. This is a workaround for a driver issue spotted on
 * nvidia and friends from time to time where multiple swaps in short
 * regression in combination with 'only redraw' adds bubbles */
	int delta = arcan_frametime() - last;
	if (delta >= 0 && delta < 8){
		arcan_timesleep(16 - delta);
	}

	last = arcan_frametime();

	if (post)
		post();
}
Ejemplo n.º 3
0
static void inject_scheduled(arcan_evctx* ctx)
{
	if (!playback_in.ptr)
		return;

	static arcan_event next_ev;
	static int32_t tickv = -1; /* -1 if no pending events */

step:
	if (tickv != -1){
		if (tickv <= arcan_frametime()){
			arcan_event_enqueue(ctx, &next_ev);
			tickv = -1;
		}
		else
			return;
	}

	ssize_t rv = unpack_rec_event(&playback_in.ptr[playback_ofs],
		playback_in.sz - playback_ofs, &next_ev, &tickv);

	if (-1 == rv){
		arcan_release_map(playback_in);
		memset(&playback_in, '\0', sizeof(playback_in));
		return;
	}

	playback_ofs += rv;
	goto step;
}
Ejemplo n.º 4
0
float arcan_event_process(arcan_evctx* ctx, arcan_tick_cb cb)
{
	int64_t base = ctx->c_ticks * ARCAN_TIMER_TICK;
	int64_t delta = arcan_frametime() - base;

	inject_scheduled(ctx);
	platform_event_process(ctx);

	if (delta > ARCAN_TIMER_TICK){
		int nticks = delta / ARCAN_TIMER_TICK;
		if (nticks > ARCAN_TICK_THRESHOLD){
			epoch += (nticks - 1) * ARCAN_TIMER_TICK;
			nticks = 1;
		}

		ctx->c_ticks += nticks;
		cb(nticks);
		arcan_bench_register_tick(nticks);
		return arcan_event_process(ctx, cb);
	}

	return (float)delta / (float)ARCAN_TIMER_TICK;
}
Ejemplo n.º 5
0
/*
 * no heavy serialization effort here, the format is intended
 * for debugging and testing. shmif- event serialization should
 * be used for other purposes.
 */
static void pack_rec_event(const struct arcan_event* const outev)
{
	if (!record_out)
		return;

	if (outev->category != EVENT_IO)
		return;

/* since this is a testing thing, we are not particularly considerate
 * in regards to compact representation */
	int32_t ioarr[11] = {0};
	ioarr[0] = arcan_frametime();
	size_t nmemb = sizeof(ioarr) / sizeof(ioarr[0]);
	ioarr[1] = outev->io.kind;
	ioarr[2] = outev->io.devid;
	ioarr[3] = outev->io.subid;

	switch(outev->io.kind){
	case EVENT_IO_TOUCH:
		ioarr[4] = outev->io.input.touch.pressure;
		ioarr[5] = outev->io.input.touch.size;
		ioarr[6] = outev->io.input.touch.x;
		ioarr[7] = outev->io.input.touch.y;
	break;
	case EVENT_IO_AXIS_MOVE:
		ioarr[4] = outev->io.input.analog.gotrel;
		for (size_t i = 0; i < nmemb - 6 &&
			i < outev->io.input.analog.nvalues; i++){
			ioarr[6+i] = outev->io.input.analog.axisval[i];
			ioarr[5]++;
		}
	break;
	case EVENT_IO_BUTTON:
		if (outev->io.devkind == EVENT_IDEVKIND_KEYBOARD){
			ioarr[4] = outev->io.devkind;
			ioarr[5] = outev->io.input.translated.active;
			ioarr[6] = outev->io.input.translated.scancode;
			ioarr[7] = outev->io.input.translated.keysym;
			ioarr[8] = outev->io.input.translated.modifiers;
		}
		else if (outev->io.devkind == EVENT_IDEVKIND_MOUSE ||
			outev->io.devkind == EVENT_IDEVKIND_GAMEDEV){
			ioarr[4] = outev->io.devkind;
			ioarr[5] = outev->io.input.digital.active;
		}
		else
			return;
	break;
	case EVENT_IO_STATUS:
		if (outev->io.devkind == EVENT_IDEVKIND_STATUS){
			ioarr[4] = outev->io.input.status.action;
		}
	break;
	default:
	break;
	}

	if (1 != fwrite(ioarr, sizeof(int32_t) * nmemb, 1, record_out)){
		fclose(record_out);
		record_out = NULL;
	}
}