int run_game(GameData *data) { int cur_shot = 0; while(cur_shot < data->num_shots) { Pacman *cur_pac_shot = (data->shots + cur_shot); draw_pacman(cur_pac_shot); draw_pebbles(data->pebbles, data->num_pebbles); *cur_pac_shot->velocity = *(data->old_velocity); Velocity *velocity = cur_pac_shot->velocity; while(!KEY_PRESSED(START)) { update_velocities(velocity); wait_for_vblank(); draw_user_velocities(data->velocity_frame_x, data->velocity_frame_y, velocity); draw_pacman(cur_pac_shot); } *(data->old_velocity ) = *cur_pac_shot->velocity;//MUST save old shot erase_frame(data->velocity_frame_x, data->bg_color); erase_frame(data->velocity_frame_y, data->bg_color); //now we run simulation fill_frame(data->indicator, GREEN); int i = 0; while(!off_screen(cur_pac_shot->frame)) { for (i = 0; i < data->num_pebbles; i++) { PacmanPebble *cur_pebble = (data->pebbles + i); check_collision(cur_pac_shot, cur_pebble); } wait_for_vblank(); erase_frame(cur_pac_shot->frame, data->bg_color); move_shot(cur_pac_shot); draw_pebbles(data->pebbles, data->num_pebbles); draw_pacman(cur_pac_shot); } erase_frame(cur_pac_shot->frame, data->bg_color); cur_shot++; } fill_frame(data->indicator, RED); return 0; }
void Pipe::Enable(bool enable) { CALLED(); addr_t pipeReg = INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset; addr_t planeReg = INTEL_DISPLAY_A_CONTROL + fPlaneOffset; // Planes always have to operate on an enabled pipe if (enable) { write32(pipeReg, read32(pipeReg) | INTEL_PIPE_ENABLED); wait_for_vblank(); write32(planeReg, read32(planeReg) | DISPLAY_CONTROL_ENABLED); } else { write32(planeReg, read32(planeReg) & ~DISPLAY_CONTROL_ENABLED); wait_for_vblank(); write32(pipeReg, read32(pipeReg) & ~INTEL_PIPE_ENABLED); } read32(INTEL_DISPLAY_A_BASE); // flush the eventually cached PCI bus writes }
static void clutter_stage_glx_redraw (ClutterStageWindow *stage_window) { ClutterBackendX11 *backend_x11; ClutterBackendGLX *backend_glx; ClutterStageX11 *stage_x11; ClutterStageGLX *stage_glx; GLXDrawable drawable; unsigned int video_sync_count; gboolean may_use_clipped_redraw; gboolean use_clipped_redraw; CLUTTER_STATIC_TIMER (painting_timer, "Redrawing", /* parent */ "Painting actors", "The time spent painting actors", 0 /* no application private data */); CLUTTER_STATIC_TIMER (swapbuffers_timer, "Redrawing", /* parent */ "glXSwapBuffers", "The time spent blocked by glXSwapBuffers", 0 /* no application private data */); CLUTTER_STATIC_TIMER (blit_sub_buffer_timer, "Redrawing", /* parent */ "glx_blit_sub_buffer", "The time spent in _glx_blit_sub_buffer", 0 /* no application private data */); stage_x11 = CLUTTER_STAGE_X11 (stage_window); if (stage_x11->xwin == None) return; stage_glx = CLUTTER_STAGE_GLX (stage_window); backend_x11 = stage_x11->backend; backend_glx = CLUTTER_BACKEND_GLX (backend_x11); CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer); if (G_LIKELY (backend_glx->can_blit_sub_buffer) && /* NB: a zero width redraw clip == full stage redraw */ stage_glx->bounding_redraw_clip.width != 0 && /* some drivers struggle to get going and produce some junk * frames when starting up... */ G_LIKELY (stage_glx->frame_count > 3) && /* While resizing a window clipped redraws are disabled to avoid * artefacts. See clutter-event-x11.c:event_translate for a * detailed explanation */ G_LIKELY (stage_x11->clipped_redraws_cool_off == 0)) { may_use_clipped_redraw = TRUE; } else may_use_clipped_redraw = FALSE; if (may_use_clipped_redraw && G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS))) use_clipped_redraw = TRUE; else use_clipped_redraw = FALSE; if (use_clipped_redraw) { CLUTTER_NOTE (CLIPPING, "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n", stage_glx->bounding_redraw_clip.x, stage_glx->bounding_redraw_clip.y, stage_glx->bounding_redraw_clip.width, stage_glx->bounding_redraw_clip.height); cogl_clip_push_window_rectangle (stage_glx->bounding_redraw_clip.x, stage_glx->bounding_redraw_clip.y, stage_glx->bounding_redraw_clip.width, stage_glx->bounding_redraw_clip.height); _clutter_stage_do_paint (stage_x11->wrapper, &stage_glx->bounding_redraw_clip); cogl_clip_pop (); } else { CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n"); _clutter_stage_do_paint (stage_x11->wrapper, NULL); } if (may_use_clipped_redraw && G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS))) { static CoglMaterial *outline = NULL; ClutterGeometry *clip = &stage_glx->bounding_redraw_clip; ClutterActor *actor = CLUTTER_ACTOR (stage_x11->wrapper); CoglHandle vbo; float x_1 = clip->x; float x_2 = clip->x + clip->width; float y_1 = clip->y; float y_2 = clip->y + clip->height; float quad[8] = { x_1, y_1, x_2, y_1, x_2, y_2, x_1, y_2 }; CoglMatrix modelview; if (outline == NULL) { outline = cogl_material_new (); cogl_material_set_color4ub (outline, 0xff, 0x00, 0x00, 0xff); } vbo = cogl_vertex_buffer_new (4); cogl_vertex_buffer_add (vbo, "gl_Vertex", 2, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, /* normalized */ 0, /* stride */ quad); cogl_vertex_buffer_submit (vbo); cogl_push_matrix (); cogl_matrix_init_identity (&modelview); _clutter_actor_apply_modelview_transform (actor, &modelview); cogl_set_modelview_matrix (&modelview); cogl_set_source (outline); cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_LINE_LOOP, 0 , 4); cogl_pop_matrix (); cogl_object_unref (vbo); } cogl_flush (); CLUTTER_TIMER_STOP (_clutter_uprof_context, painting_timer); drawable = stage_glx->glxwin ? stage_glx->glxwin : stage_x11->xwin; /* If we might ever use _clutter_backend_glx_blit_sub_buffer then we * always need to keep track of the video_sync_count so that we can * throttle blits. * * Note: we get the count *before* we issue any glXCopySubBuffer or * blit_sub_buffer request in case the count would go up before * returning control to us. */ if (backend_glx->can_blit_sub_buffer && backend_glx->get_video_sync) backend_glx->get_video_sync (&video_sync_count); /* push on the screen */ if (use_clipped_redraw) { ClutterGeometry *clip = &stage_glx->bounding_redraw_clip; ClutterGeometry copy_area; ClutterActor *actor; CLUTTER_NOTE (BACKEND, "_glx_blit_sub_buffer (window: 0x%lx, " "x: %d, y: %d, " "width: %d, height: %d)", (unsigned long) drawable, stage_glx->bounding_redraw_clip.x, stage_glx->bounding_redraw_clip.y, stage_glx->bounding_redraw_clip.width, stage_glx->bounding_redraw_clip.height); /* XXX: It seems there will be a race here in that the stage * window may be resized before glXCopySubBufferMESA is handled * and so we may copy the wrong region. I can't really see how * we can handle this with the current state of X but at least * in this case a full redraw should be queued by the resize * anyway so it should only exhibit temporary artefacts. */ actor = CLUTTER_ACTOR (stage_x11->wrapper); copy_area.y = clutter_actor_get_height (actor) - clip->y - clip->height; copy_area.x = clip->x; copy_area.width = clip->width; copy_area.height = clip->height; /* glXCopySubBufferMESA and glBlitFramebuffer are not integrated * with the glXSwapIntervalSGI mechanism which we usually use to * throttle the Clutter framerate to the vertical refresh and so * we have to manually wait for the vblank period... */ /* Here 'is_synchronized' only means that the blit won't cause a * tear, ie it won't prevent multiple blits per retrace if they * can all be performed in the blanking period. If that's the * case then we still want to use the vblank sync menchanism but * we only need it to throttle redraws. */ if (!backend_glx->blit_sub_buffer_is_synchronized) { /* XXX: note that glXCopySubBuffer, at least for Intel, is * synchronized with the vblank but glBlitFramebuffer may * not be so we use the same scheme we do when calling * glXSwapBuffers without the swap_control extension and * call glFinish () before waiting for the vblank period. * * See where we call glXSwapBuffers for more details. */ glFinish (); wait_for_vblank (backend_glx); } else if (backend_glx->get_video_sync) { /* If we have the GLX_SGI_video_sync extension then we can * be a bit smarter about how we throttle blits by avoiding * any waits if we can see that the video sync count has * already progressed. */ if (backend_glx->last_video_sync_count == video_sync_count) wait_for_vblank (backend_glx); } else wait_for_vblank (backend_glx); CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer); _clutter_backend_glx_blit_sub_buffer (backend_glx, drawable, copy_area.x, copy_area.y, copy_area.width, copy_area.height); CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer); } else { CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)", backend_x11->xdpy, (unsigned long) drawable); /* If we have GLX swap buffer events then glXSwapBuffers will return * immediately and we need to track that there is a swap in * progress... */ if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) stage_glx->pending_swaps++; if (backend_glx->vblank_type != CLUTTER_VBLANK_GLX_SWAP && backend_glx->vblank_type != CLUTTER_VBLANK_NONE) { /* If we are going to wait for VBLANK manually, we not only * need to flush out pending drawing to the GPU before we * sleep, we need to wait for it to finish. Otherwise, we * may end up with the situation: * * - We finish drawing - GPU drawing continues * - We go to sleep - GPU drawing continues * VBLANK - We call glXSwapBuffers - GPU drawing continues * - GPU drawing continues * - Swap buffers happens * * Producing a tear. Calling glFinish() first will cause us * to properly wait for the next VBLANK before we swap. This * obviously does not happen when we use _GLX_SWAP and let * the driver do the right thing */ glFinish (); wait_for_vblank (backend_glx); } CLUTTER_TIMER_START (_clutter_uprof_context, swapbuffers_timer); glXSwapBuffers (backend_x11->xdpy, drawable); CLUTTER_TIMER_STOP (_clutter_uprof_context, swapbuffers_timer); _cogl_swap_buffers_notify (); } backend_glx->last_video_sync_count = video_sync_count; /* reset the redraw clipping for the next paint... */ stage_glx->initialized_redraw_clip = FALSE; stage_glx->frame_count++; }
void set_display_power_mode(uint32 mode) { uint32 monitorMode = 0; if (mode == B_DPMS_ON) { uint32 pll = read32(INTEL_DISPLAY_A_PLL); if ((pll & DISPLAY_PLL_ENABLED) == 0) { // reactivate PLL write32(INTEL_DISPLAY_A_PLL, pll); read32(INTEL_DISPLAY_A_PLL); spin(150); write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); read32(INTEL_DISPLAY_A_PLL); spin(150); write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); read32(INTEL_DISPLAY_A_PLL); spin(150); } pll = read32(INTEL_DISPLAY_B_PLL); if ((pll & DISPLAY_PLL_ENABLED) == 0) { // reactivate PLL write32(INTEL_DISPLAY_B_PLL, pll); read32(INTEL_DISPLAY_B_PLL); spin(150); write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); read32(INTEL_DISPLAY_B_PLL); spin(150); write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); read32(INTEL_DISPLAY_B_PLL); spin(150); } enable_display_pipe(true); enable_display_plane(true); } wait_for_vblank(); switch (mode) { case B_DPMS_ON: monitorMode = DISPLAY_MONITOR_ON; break; case B_DPMS_SUSPEND: monitorMode = DISPLAY_MONITOR_SUSPEND; break; case B_DPMS_STAND_BY: monitorMode = DISPLAY_MONITOR_STAND_BY; break; case B_DPMS_OFF: monitorMode = DISPLAY_MONITOR_OFF; break; } if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { write32(INTEL_DISPLAY_A_ANALOG_PORT, (read32(INTEL_DISPLAY_A_ANALOG_PORT) & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); } if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { write32(INTEL_DISPLAY_B_DIGITAL_PORT, (read32(INTEL_DISPLAY_B_DIGITAL_PORT) & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); // TODO: monitorMode? } if (mode != B_DPMS_ON) { enable_display_plane(false); wait_for_vblank(); enable_display_pipe(false); } if (mode == B_DPMS_OFF) { write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL) | DISPLAY_PLL_ENABLED); write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL) | DISPLAY_PLL_ENABLED); read32(INTEL_DISPLAY_B_PLL); // flush the possibly cached PCI bus writes spin(150); } if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0) enable_lvds_panel(mode == B_DPMS_ON); read32(INTEL_DISPLAY_A_BASE); // flush the possibly cached PCI bus writes }