Beispiel #1
0
        void shoot(wl_resource *resource)
        {
            if (!wl_shm_buffer_get(resource)) {
                failed();
                return;
            }

            wl_shm_buffer *shm = wl_shm_buffer_get(resource);
            int width = wl_shm_buffer_get_width(shm);
            int height = wl_shm_buffer_get_height(shm);
            int stride = wl_shm_buffer_get_stride(shm);
            QSize size = m_surface->contentSize();

            if (stride != size.width() * 4 || height != size.height()) {
                failed();
                return;
            }

            wl_shm_buffer_begin_access(shm);

            void *data = wl_shm_buffer_get_data(shm);
            m_surface->copyContent(data, stride * height, QRect(0, 0, width, height));

            wl_shm_buffer_end_access(shm);

            orbital_surface_screenshot_send_done(m_resource);
            wl_resource_destroy(m_resource);
            delete this;
        }
Beispiel #2
0
static void
surface_damaged (CoglandSurface *surface,
                 int32_t x,
                 int32_t y,
                 int32_t width,
                 int32_t height)
{
  if (surface->buffer_ref.buffer &&
      surface->texture)
    {
      struct wl_shm_buffer *shm_buffer =
        wl_shm_buffer_get (surface->buffer_ref.buffer->resource);

      if (shm_buffer)
        cogl_wayland_texture_set_region_from_shm_buffer (surface->texture,
                                                         x, y,
                                                         width,
                                                         height,
                                                         shm_buffer,
                                                         x, y,
                                                         0, /* level */
                                                         NULL);
    }

  cogland_queue_redraw (surface->compositor);
}
Beispiel #3
0
static bool
surface_attach(struct ctx *context, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer)
{
   assert(context && bound && surface);

   struct wl_resource *wl_buffer;
   if (!buffer || !(wl_buffer = convert_to_wl_resource(buffer, "buffer"))) {
      surface_destroy(context, bound, surface);
      return true;
   }

   EGLint format;
   bool attached = false;

   struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(wl_buffer);
   if (shm_buffer) {
      attached = shm_attach(surface, buffer, shm_buffer);
   } else if (wlc_context_query_buffer(bound, (void*)wl_buffer, EGL_TEXTURE_FORMAT, &format)) {
      attached = egl_attach(context, bound, surface, buffer, format);
   } else {
      /* unknown buffer */
      wlc_log(WLC_LOG_WARN, "Unknown buffer");
   }

   if (attached)
      wlc_dlog(WLC_DBG_RENDER, "-> Attached surface (%" PRIuWLC ") with buffer of size (%ux%u)", convert_to_wlc_resource(surface), buffer->size.w, buffer->size.h);

   return attached;
}
static void wstRendererSurfaceCommit( WstRenderer *renderer, WstRenderSurface *surface, struct wl_resource *resource )
{
   WstRendererNX *rendererNX= (WstRendererNX*)renderer->renderer;
   EGLint value;

   if ( resource )
   {
      if ( wl_shm_buffer_get( resource ) )
      {
         wstRendererNXCommitShm( rendererNX, surface, resource );
      }
      #ifdef ENABLE_SBPROTOCOL
      else if ( WstSBBufferGet( resource ) )
      {
         wstRendererNXCommitSB( rendererNX, surface, resource );
      }
      #endif
      #if defined (WESTEROS_HAVE_WAYLAND_EGL)
      else if ( wl_egl_get_device_buffer( resource ) )
      {
         wstRendererNXCommitBNXS( rendererNX, surface, resource );
      }
      #endif
      else
      {
         printf("wstRendererSurfaceCommit: unsupported buffer type\n");
      }
   }
   else
   {
      surface->surfacePending= 0;
      NEXUS_SurfaceClient_Clear(surface->gfxSurfaceClient);
   }
}
Beispiel #5
0
gboolean
meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
{
  EGLint format;
  MetaBackend *backend = meta_get_backend ();
  MetaEgl *egl = meta_backend_get_egl (backend);
  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
  CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
  EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
#ifdef HAVE_WAYLAND_EGLSTREAM
  MetaWaylandEglStream *stream;
#endif
  MetaWaylandDmaBufBuffer *dma_buf;

  if (wl_shm_buffer_get (buffer->resource) != NULL)
    {
      buffer->type = META_WAYLAND_BUFFER_TYPE_SHM;
      return TRUE;
    }

#ifdef HAVE_WAYLAND_EGLSTREAM
  stream = meta_wayland_egl_stream_new (buffer, NULL);
  if (stream)
    {
      CoglTexture2D *texture;

      texture = meta_wayland_egl_stream_create_texture (stream, NULL);
      if (!texture)
        return FALSE;

      buffer->egl_stream.stream = stream;
      buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
      buffer->egl_stream.texture = COGL_TEXTURE (texture);
      buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);

      return TRUE;
    }
#endif /* HAVE_WAYLAND_EGLSTREAM */

  if (meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
                                     EGL_TEXTURE_FORMAT, &format,
                                     NULL))
    {
      buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_IMAGE;
      return TRUE;
    }

  dma_buf = meta_wayland_dma_buf_from_buffer (buffer);
  if (dma_buf)
    {
      buffer->dma_buf.dma_buf = dma_buf;
      buffer->type = META_WAYLAND_BUFFER_TYPE_DMA_BUF;
      return TRUE;
    }

  return FALSE;
}
QImage SurfaceBuffer::image() const
{
    if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
        int width = wl_shm_buffer_get_width(shmBuffer);
        int height = wl_shm_buffer_get_height(shmBuffer);
        int bytesPerLine = wl_shm_buffer_get_stride(shmBuffer);
        uchar *data = static_cast<uchar *>(wl_shm_buffer_get_data(shmBuffer));
        return QImage(data, width, height, bytesPerLine, QImage::Format_ARGB32_Premultiplied);
    }

    return QImage();
}
Beispiel #7
0
bool SurfaceBuffer::isShmBuffer() const
{
    if (!m_is_shm_resolved) {
#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2)
        m_shmBuffer = wl_shm_buffer_get(m_buffer);
#else
        if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data)))
            m_shmBuffer = static_cast<struct ::wl_buffer*>(m_buffer->data);
#endif
        m_is_shm_resolved = true;
    }
    return m_shmBuffer != 0;
}
static void
pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
	struct pixman_surface_state *ps = get_surface_state(es);
	struct wl_shm_buffer *shm_buffer;
	pixman_format_code_t pixman_format;

	weston_buffer_reference(&ps->buffer_ref, buffer);

	if (ps->image) {
		pixman_image_unref(ps->image);
		ps->image = NULL;
	}

	if (!buffer)
		return;
	
	shm_buffer = wl_shm_buffer_get(buffer->resource);

	if (! shm_buffer) {
		weston_log("Pixman renderer supports only SHM buffers\n");
		weston_buffer_reference(&ps->buffer_ref, NULL);
		return;
	}

	switch (wl_shm_buffer_get_format(shm_buffer)) {
	case WL_SHM_FORMAT_XRGB8888:
		pixman_format = PIXMAN_x8r8g8b8;
		break;
	case WL_SHM_FORMAT_ARGB8888:
		pixman_format = PIXMAN_a8r8g8b8;
		break;
	case WL_SHM_FORMAT_RGB565:
		pixman_format = PIXMAN_r5g6b5;
		break;
	default:
		weston_log("Unsupported SHM buffer format\n");
		weston_buffer_reference(&ps->buffer_ref, NULL);
		return;
	break;
	}

	buffer->shm_buffer = shm_buffer;
	buffer->width = wl_shm_buffer_get_width(shm_buffer);
	buffer->height = wl_shm_buffer_get_height(shm_buffer);

	ps->image = pixman_image_create_bits(pixman_format,
		buffer->width, buffer->height,
		wl_shm_buffer_get_data(shm_buffer),
		wl_shm_buffer_get_stride(shm_buffer));
}
Beispiel #9
0
static gboolean
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
                           CoglTexture       *texture,
                           cairo_region_t    *region,
                           GError           **error)
{
  struct wl_shm_buffer *shm_buffer;
  int i, n_rectangles;
  gboolean set_texture_failed = FALSE;

  n_rectangles = cairo_region_num_rectangles (region);

  shm_buffer = wl_shm_buffer_get (buffer->resource);
  wl_shm_buffer_begin_access (shm_buffer);

  for (i = 0; i < n_rectangles; i++)
    {
      const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
      int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
      CoglPixelFormat format;
      int bpp;
      cairo_rectangle_int_t rect;

      shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
      bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
      cairo_region_get_rectangle (region, i, &rect);

      if (!_cogl_texture_set_region (texture,
                                     rect.width, rect.height,
                                     format,
                                     stride,
                                     data + rect.x * bpp + rect.y * stride,
                                     rect.x, rect.y,
                                     0,
                                     error))
        {
          set_texture_failed = TRUE;
          break;
        }
    }

  wl_shm_buffer_end_access (shm_buffer);

  return !set_texture_failed;
}
QSize SurfaceBuffer::size() const
{
    if (!m_buffer)
        return QSize();

    if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
        int width = wl_shm_buffer_get_width(shmBuffer);
        int height = wl_shm_buffer_get_height(shmBuffer);
        return QSize(width, height);
    }
#ifdef QT_WAYLAND_COMPOSITOR_GL
    if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) {
        return integration->bufferSize(m_buffer);
    }
#endif

    return QSize();
}
Beispiel #11
0
static void
noop_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
	struct wl_shm_buffer *shm_buffer;
	uint8_t *data;
	uint32_t size, i, width, height, stride;
	volatile unsigned char unused = 0; /* volatile so it's not optimized out */

	if (!buffer)
		return;

	shm_buffer = wl_shm_buffer_get(buffer->resource);

	if (!shm_buffer) {
		weston_log("No-op renderer supports only SHM buffers\n");
		return;
	}

	data = wl_shm_buffer_get_data(shm_buffer);
	stride = wl_shm_buffer_get_stride(shm_buffer);
	width = wl_shm_buffer_get_width(shm_buffer);
	height = wl_shm_buffer_get_height(shm_buffer);
	size = stride * height;

	/* Access the buffer data to make sure the buffer's client gets killed
	 * if the buffer size is invalid. This makes the bad_buffer test pass.
	 * This can be removed if we start reading the buffer contents
	 * somewhere else, e.g. in repaint_output(). */
	wl_shm_buffer_begin_access(shm_buffer);
	for (i = 0; i < size; i++)
		unused ^= data[i];
	wl_shm_buffer_end_access(shm_buffer);

	buffer->shm_buffer = shm_buffer;
	buffer->width = width;
	buffer->height = height;
}
Beispiel #12
0
CoglTexture2D *
cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
        struct wl_resource *buffer,
        CoglError **error)
{
    struct wl_shm_buffer *shm_buffer;
    CoglTexture2D *tex = NULL;

    shm_buffer = wl_shm_buffer_get (buffer);

    if (shm_buffer)
    {
        int stride = wl_shm_buffer_get_stride (shm_buffer);
        int width = wl_shm_buffer_get_width (shm_buffer);
        int height = wl_shm_buffer_get_height (shm_buffer);
        CoglPixelFormat format;
        CoglTextureComponents components;
        CoglBitmap *bmp;

        shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);

        bmp = cogl_bitmap_new_for_data (ctx,
                                        width, height,
                                        format,
                                        stride,
                                        wl_shm_buffer_get_data (shm_buffer));

        tex = cogl_texture_2d_new_from_bitmap (bmp);

        cogl_texture_set_components (COGL_TEXTURE (tex), components);

        cogl_object_unref (bmp);

        if (!cogl_texture_allocate (COGL_TEXTURE (tex), error))
        {
            cogl_object_unref (tex);
            return NULL;
        }
        else
            return tex;
    }
    else
    {
        int format, width, height;

        if (_cogl_egl_query_wayland_buffer (ctx,
                                            buffer,
                                            EGL_TEXTURE_FORMAT,
                                            &format) &&
                _cogl_egl_query_wayland_buffer (ctx,
                                                buffer,
                                                EGL_WIDTH,
                                                &width) &&
                _cogl_egl_query_wayland_buffer (ctx,
                                                buffer,
                                                EGL_HEIGHT,
                                                &height))
        {
            EGLImageKHR image;
            CoglPixelFormat internal_format;

            _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
                                      COGL_RENDERER_CONSTRAINT_USES_EGL,
                                      NULL);

            switch (format)
            {
            case EGL_TEXTURE_RGB:
                internal_format = COGL_PIXEL_FORMAT_RGB_888;
                break;
            case EGL_TEXTURE_RGBA:
                internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
                break;
            default:
                _cogl_set_error (error,
                                 COGL_SYSTEM_ERROR,
                                 COGL_SYSTEM_ERROR_UNSUPPORTED,
                                 "Can't create texture from unknown "
                                 "wayland buffer format %d\n", format);
                return NULL;
            }

            image = _cogl_egl_create_image (ctx,
                                            EGL_WAYLAND_BUFFER_WL,
                                            buffer,
                                            NULL);
            tex = _cogl_egl_texture_2d_new_from_image (ctx,
                    width, height,
                    internal_format,
                    image,
                    error);
            _cogl_egl_destroy_image (ctx, image);
            return tex;
        }
    }

    _cogl_set_error (error,
                     COGL_SYSTEM_ERROR,
                     COGL_SYSTEM_ERROR_UNSUPPORTED,
                     "Can't create texture from unknown "
                     "wayland buffer type\n");
    return NULL;
}
Beispiel #13
0
static gboolean
shm_buffer_attach (MetaWaylandBuffer  *buffer,
                   CoglTexture       **texture,
                   gboolean           *changed_texture,
                   GError            **error)
{
  MetaBackend *backend = meta_get_backend ();
  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
  CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
  struct wl_shm_buffer *shm_buffer;
  int stride, width, height;
  CoglPixelFormat format;
  CoglTextureComponents components;
  CoglBitmap *bitmap;
  CoglTexture *new_texture;

  shm_buffer = wl_shm_buffer_get (buffer->resource);
  stride = wl_shm_buffer_get_stride (shm_buffer);
  width = wl_shm_buffer_get_width (shm_buffer);
  height = wl_shm_buffer_get_height (shm_buffer);
  shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);

  if (*texture &&
      cogl_texture_get_width (*texture) == width &&
      cogl_texture_get_height (*texture) == height &&
      cogl_texture_get_components (*texture) == components &&
      _cogl_texture_get_format (*texture) == format)
    {
      buffer->is_y_inverted = TRUE;
      *changed_texture = FALSE;
      return TRUE;
    }

  cogl_clear_object (texture);

  wl_shm_buffer_begin_access (shm_buffer);

  bitmap = cogl_bitmap_new_for_data (cogl_context,
                                     width, height,
                                     format,
                                     stride,
                                     wl_shm_buffer_get_data (shm_buffer));

  new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
  cogl_texture_set_components (new_texture, components);

  if (!cogl_texture_allocate (new_texture, error))
    {
      g_clear_pointer (&new_texture, cogl_object_unref);
      if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
        {
          CoglTexture2DSliced *texture_sliced;

          g_clear_error (error);

          texture_sliced =
            cogl_texture_2d_sliced_new_from_bitmap (bitmap,
                                                    COGL_TEXTURE_MAX_WASTE);
          new_texture = COGL_TEXTURE (texture_sliced);
          cogl_texture_set_components (new_texture, components);

          if (!cogl_texture_allocate (new_texture, error))
            g_clear_pointer (&new_texture, cogl_object_unref);
        }
    }

  cogl_object_unref (bitmap);

  wl_shm_buffer_end_access (shm_buffer);

  if (!new_texture)
    return FALSE;

  *texture = new_texture;
  *changed_texture = TRUE;
  buffer->is_y_inverted = TRUE;

  return TRUE;
}
static void wstRendererNXCommitShm( WstRendererNX *renderer, WstRenderSurface *surface, struct wl_resource *resource )
{
   struct wl_shm_buffer *shmBuffer;
   int width, height, stride;
   int pixelFormat, i;
   void *data;
   NEXUS_SurfaceMemory mem;
   NEXUS_SurfaceComposition composition;            
   NEXUS_SurfaceHandle nexusSurface= 0;

   shmBuffer= wl_shm_buffer_get( resource );
   if ( shmBuffer )
   {
      width= wl_shm_buffer_get_width(shmBuffer);
      height= wl_shm_buffer_get_height(shmBuffer);
      stride= wl_shm_buffer_get_stride(shmBuffer);

      // The SHM formats describe the structure of the color channels for a pixel as
      // they would appear in a machine register not the byte order in memory.  For 
      // example WL_SHM_FORMAT_ARGB8888 is a 32 bit pixel with alpha in the 8 most significant
      // bits and blue in the 8 list significant bits.  On a little endian machine the
      // byte order in memory would be B, G, R, A.
      switch( wl_shm_buffer_get_format(shmBuffer) )
      {
         case WL_SHM_FORMAT_ARGB8888:
            pixelFormat= NEXUS_PixelFormat_eA8_R8_G8_B8;
            break;
         case WL_SHM_FORMAT_XRGB8888:
            pixelFormat= NEXUS_PixelFormat_eX8_R8_G8_B8;
            break;
         case WL_SHM_FORMAT_BGRA8888:
            pixelFormat= NEXUS_PixelFormat_eB8_G8_R8_A8;
            break;
         case WL_SHM_FORMAT_BGRX8888:
            pixelFormat= NEXUS_PixelFormat_eB8_G8_R8_X8;
            break;
         case WL_SHM_FORMAT_RGB565:
            pixelFormat= NEXUS_PixelFormat_eR5_G6_B5;
            break;
         case WL_SHM_FORMAT_ARGB4444:
            pixelFormat= NEXUS_PixelFormat_eA4_R4_G4_B4;
            break;
         default:
            pixelFormat= NEXUS_PixelFormat_eUnknown;
            break;
      }
      if ( pixelFormat != NEXUS_PixelFormat_eUnknown )
      {
         wl_shm_buffer_begin_access(shmBuffer);
         data= wl_shm_buffer_get_data(shmBuffer);
         
         if ( 
              (surface->surfaceWidth != width) ||
              (surface->surfaceHeight != height) ||
              (surface->surfacePixelFormat != pixelFormat)
            )
         {
            wstRendererAllocSurfaces( renderer, surface, width, height, pixelFormat );
         }
         
         nexusSurface= surface->surface[surface->back];
         if ( nexusSurface )
         {            
            unsigned char *src, *dest;
            
            NEXUS_Surface_GetMemory( nexusSurface, &mem );

            src= (unsigned char *)data;
            dest= (unsigned char *)mem.buffer;

            if ( mem.pitch == stride )
            {
               memcpy( dest, src, height*stride );
               dest += height*mem.pitch;
            }
            else
            {               
               for( i= 0; i < height; ++i )
               {
                  memcpy( dest, src, stride );
                  if ( stride < mem.pitch )
                  {
                     memset( dest+stride, 0, (mem.pitch-stride) );
                  }
                  dest += mem.pitch;
                  src += stride;
               }
            }
            if ( height < surface->surfaceHeight )
            {
               memset( dest, 0, mem.pitch*(surface->surfaceHeight-height) );
            }
            NEXUS_Surface_Flush( nexusSurface );

            if ( !surface->sizeOverride )
            {
               surface->width= surface->surfaceWidth;
               surface->height= surface->surfaceHeight;
            }

            if ( !renderer->isDelegate )
            {
               NxClient_GetSurfaceClientComposition(surface->allocResults.surfaceClient[0].id, &composition);
               composition.position.width= surface->width;
               composition.position.height= surface->height;
               NxClient_SetSurfaceClientComposition(surface->allocResults.surfaceClient[0].id, &composition);
            }

            unsigned n= 0;
            do
            {
               NEXUS_SurfaceHandle surface_list[10];
               int rc = NEXUS_SurfaceClient_RecycleSurface(surface->gfxSurfaceClient, surface_list, 10, &n);
               if (rc) break;
            }
            while (n >= 10);

            surface->surfacePending= nexusSurface;
         }

         wl_shm_buffer_end_access(shmBuffer);
         
         ++surface->back;
         if ( surface->back >= NUM_SURFACES )
         {
            surface->back= 0;
         }
      }
   }
}