コード例 #1
0
ファイル: plugin.c プロジェクト: pkt/pkt-plymouth
static ply_renderer_head_t *
ply_renderer_head_new (ply_renderer_backend_t *backend,
                       drmModeConnector       *connector,
                       uint32_t                encoder_id,
                       uint32_t                controller_id,
                       uint32_t                console_buffer_id,
                       drmModeModeInfo        *mode)
{
  ply_renderer_head_t *head;

  head = calloc (1, sizeof (ply_renderer_head_t));

  head->backend = backend;
  head->connector = connector;
  head->encoder_id = encoder_id;
  head->controller_id = controller_id;
  head->console_buffer_id = console_buffer_id;
  head->mode = mode;

  head->area.x = 0;
  head->area.y = 0;
  head->area.width = mode->hdisplay;
  head->area.height = mode->vdisplay;

  head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);

  ply_trace ("Creating %ldx%ld renderer head", head->area.width, head->area.height);
  ply_pixel_buffer_fill_with_color (head->pixel_buffer, NULL,
                                    0.0, 0.0, 0.0, 1.0);

  return head;
}
コード例 #2
0
ファイル: plugin.c プロジェクト: AtsKiYsPoYl/plymouth
static ply_renderer_head_t *
ply_renderer_head_new (ply_renderer_backend_t *backend,
                       drmModeConnector       *connector,
                       int                     connector_mode_index,
                       uint32_t                encoder_id,
                       uint32_t                controller_id,
                       uint32_t                console_buffer_id)
{
  ply_renderer_head_t *head;
  drmModeModeInfo *mode;

  head = calloc (1, sizeof (ply_renderer_head_t));

  head->backend = backend;
  head->encoder_id = encoder_id;
  head->connector_ids = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_UINT32);
  head->controller_id = controller_id;
  head->console_buffer_id = console_buffer_id;

  assert (connector_mode_index < connector->count_modes);
  mode = &connector->modes[connector_mode_index];

  head->connector0 = connector;
  head->connector0_mode_index = connector_mode_index;

  head->area.x = 0;
  head->area.y = 0;
  head->area.width = mode->hdisplay;
  head->area.height = mode->vdisplay;

  ply_renderer_head_add_connector (head, connector, connector_mode_index);
  assert (ply_array_get_size (head->connector_ids) > 0);

  head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);

  ply_trace ("Creating %ldx%ld renderer head", head->area.width, head->area.height);
  ply_pixel_buffer_fill_with_color (head->pixel_buffer, NULL,
                                    0.0, 0.0, 0.0, 1.0);

  return head;
}
コード例 #3
0
ファイル: ply-image.c プロジェクト: AtsKiYsPoYl/plymouth
bool
ply_image_load (ply_image_t *image)
{
  png_struct *png;
  png_info *info;
  png_uint_32 width, height, row;
  int bits_per_pixel, color_type, interlace_method;
  png_byte **rows;
  uint32_t *bytes;
  FILE *fp;
  
  assert (image != NULL);
  
  fp = fopen (image->filename, "r");
  if (fp == NULL)
    return false;
  
  png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  assert (png != NULL);

  info = png_create_info_struct (png);
  assert (info != NULL);

  png_init_io (png, fp);

  if (setjmp (png_jmpbuf (png)) != 0)
    {
      fclose (fp);
      return false;
    }

  png_read_info (png, info);
  png_get_IHDR (png, info,
                &width, &height, &bits_per_pixel,
                &color_type, &interlace_method, NULL, NULL);

  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb (png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
    png_set_expand_gray_1_2_4_to_8 (png);

  if (png_get_valid (png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha (png);

  if (bits_per_pixel == 16)
    png_set_strip_16 (png);

  if (bits_per_pixel < 8)
    png_set_packing (png);

  if ((color_type == PNG_COLOR_TYPE_GRAY)
      || (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
    png_set_gray_to_rgb (png);

  if (interlace_method != PNG_INTERLACE_NONE)
    png_set_interlace_handling (png);

  png_set_filler (png, 0xff, PNG_FILLER_AFTER);

  png_set_read_user_transform_fn (png, transform_to_argb32);

  png_read_update_info (png, info);

  rows = malloc (height * sizeof (png_byte *));
  image->buffer = ply_pixel_buffer_new (width, height);
  
  bytes = ply_pixel_buffer_get_argb32_data (image->buffer);

  for (row = 0; row < height; row++)
    rows[row] = (png_byte*) &bytes[row * width];

  png_read_image (png, rows);

  free (rows);
  png_read_end (png, info);
  fclose (fp);
  png_destroy_read_struct (&png, &info, NULL);

  return true;
}
コード例 #4
0
void
ply_progress_animation_draw (ply_progress_animation_t *progress_animation)
{
  int number_of_frames;
  int frame_number;
  ply_image_t * const * frames;
  uint32_t *previous_frame_data, *frame_data;

  if (progress_animation->is_hidden)
    return;

  number_of_frames = ply_array_get_size (progress_animation->frames);

  if (number_of_frames == 0)
    return;

  frame_number = progress_animation->percent_done * (number_of_frames - 1);

  if (progress_animation->previous_frame_number != frame_number &&
      progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE &&
      progress_animation->transition_duration > 0.0)
    {
      progress_animation->is_transitioning = true;
      progress_animation->transition_start_time = ply_get_timestamp ();
    }

  frames = (ply_image_t * const *) ply_array_get_elements (progress_animation->frames);

  progress_animation->frame_area.x = progress_animation->area.x;
  progress_animation->frame_area.y = progress_animation->area.y;
  frame_data = ply_image_get_data (frames[frame_number]);

  if (progress_animation->is_transitioning)
    {
      double now;
      double fade_percentage;
      double fade_out_opacity;
      int width, height;
      uint32_t* faded_data;
      now = ply_get_timestamp ();

      fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration;

      if (fade_percentage >= 1.0)
        progress_animation->is_transitioning = false;
      fade_percentage = CLAMP (fade_percentage, 0.0, 1.0);

      if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE)
        {
          width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
          height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
          progress_animation->frame_area.width = width;
          progress_animation->frame_area.height = height;

          ply_pixel_buffer_free (progress_animation->last_rendered_frame);
          progress_animation->last_rendered_frame = ply_pixel_buffer_new (width, height);
          faded_data = ply_pixel_buffer_get_argb32_data (progress_animation->last_rendered_frame);

          image_fade_merge (frames[frame_number - 1], frames[frame_number], fade_percentage, width, height, faded_data);

          ply_pixel_display_draw_area (progress_animation->display,
                                       progress_animation->frame_area.x,
                                       progress_animation->frame_area.y,
                                       progress_animation->frame_area.width,
                                       progress_animation->frame_area.height);
        }
      else
        {
          ply_rectangle_t fill_area;

          previous_frame_data = ply_image_get_data (frames[frame_number - 1]);
          if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER)
            {
              ply_pixel_buffer_free (progress_animation->last_rendered_frame);
              progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]);
              progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]);

              progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width,
                                                                              progress_animation->frame_area.height);
              fill_area.x = 0;
              fill_area.y = 0;
              fill_area.width = progress_animation->frame_area.width;
              fill_area.height = progress_animation->frame_area.height;
              ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame,
                                                      &fill_area, 0, 0,
                                                      previous_frame_data);
            }
          else
            {
              fade_out_opacity = 1.0 - fade_percentage;
              progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]);
              progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]);

              fill_area.x = 0;
              fill_area.y = 0;
              fill_area.width = progress_animation->frame_area.width;
              fill_area.height = progress_animation->frame_area.height;
              ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame,
                                                                 &fill_area, 0, 0,
                                                                 previous_frame_data, fade_out_opacity);
            }

          progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]);
          progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]);
          fill_area.x = 0;
          fill_area.y = 0;
          fill_area.width = progress_animation->frame_area.width;
          fill_area.height = progress_animation->frame_area.height;
          ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame,
                                                             &fill_area, 0, 0,
                                                             frame_data, fade_percentage);

          width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
          height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
          progress_animation->frame_area.width = width;
          progress_animation->frame_area.height = height;
        }
    }
  else
    {
      ply_rectangle_t fill_area;

      ply_pixel_buffer_free (progress_animation->last_rendered_frame);
      progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]);
      progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]);
      progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width,
                                                                      progress_animation->frame_area.height);

      fill_area.x = 0;
      fill_area.y = 0;
      fill_area.width = progress_animation->frame_area.width;
      fill_area.height = progress_animation->frame_area.height;
      ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame,
                                              &fill_area, 0, 0,
                                              frame_data);
    }

  progress_animation->previous_frame_number = frame_number;

  ply_pixel_display_draw_area (progress_animation->display,
                               progress_animation->frame_area.x,
                               progress_animation->frame_area.y,
                               progress_animation->frame_area.width,
                               progress_animation->frame_area.height);
}
コード例 #5
0
ファイル: plugin.c プロジェクト: AtsKiYsPoYl/plymouth
static bool
ply_renderer_head_set_scan_out_buffer_to_console (ply_renderer_backend_t *backend,
                                                  ply_renderer_head_t    *head,
                                                  bool                    should_set_to_black)
{
  unsigned long width;
  unsigned long height;
  unsigned long row_stride;
  uint32_t *shadow_buffer;
  ply_pixel_buffer_t *pixel_buffer;
  char *map_address;
  ply_rectangle_t area;

  if (!backend->driver_interface->fetch_buffer (backend->driver,
                                               head->console_buffer_id,
                                               &width, &height, &row_stride))
    return false;

  if (!backend->driver_interface->map_buffer (backend->driver,
                                              head->console_buffer_id))
    {
      backend->driver_interface->destroy_buffer (backend->driver,
                                                 head->console_buffer_id);
      return false;
    }

  if (head->area.width != width || head->area.height != height)
    {
      /* Force black if the fb console resolution doesn't match our resolution
       */
      area.x = 0;
      area.y = 0;
      area.width = width;
      area.height = height;

      should_set_to_black = true;
      ply_trace ("Console fb is %ldx%ld and screen contents are %ldx%ld. "
                 "They aren't the same dimensions; forcing black",
                 width, height, head->area.width, head->area.height);
    }
  else
    area = head->area;

  if (should_set_to_black)
    {
      pixel_buffer = ply_pixel_buffer_new (width, height);
      shadow_buffer = ply_pixel_buffer_get_argb32_data (pixel_buffer);
    }
  else
    {
      pixel_buffer = NULL;
      shadow_buffer = ply_pixel_buffer_get_argb32_data (head->pixel_buffer);
    }

  ply_trace ("Drawing %s to console fb", should_set_to_black? "black" : "screen contents");
  map_address =
        backend->driver_interface->begin_flush (backend->driver,
                                                head->console_buffer_id);

  flush_area ((char *) shadow_buffer, area.width * 4,
              map_address, row_stride, &area);

  backend->driver_interface->end_flush (backend->driver,
                                        head->console_buffer_id);

  backend->driver_interface->unmap_buffer (backend->driver,
                                           head->console_buffer_id);

  ply_trace ("Setting scan out hardware to console fb");
  ply_renderer_head_set_scan_out_buffer (backend,
                                         head, head->console_buffer_id);

  backend->driver_interface->destroy_buffer (backend->driver,
                                             head->console_buffer_id);

  if (pixel_buffer != NULL)
    ply_pixel_buffer_free (pixel_buffer);

  return true;
}