Exemple #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;
        }
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();
}
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));
}
Exemple #4
0
static bool
shm_attach(struct wlc_surface *surface, struct wlc_buffer *buffer, struct wl_shm_buffer *shm_buffer)
{
   assert(surface && buffer && shm_buffer);

   buffer->shm_buffer = shm_buffer;
   buffer->size.w = wl_shm_buffer_get_width(shm_buffer);
   buffer->size.h = wl_shm_buffer_get_height(shm_buffer);

   GLint pitch;
   GLenum gl_format, gl_pixel_type;
   switch (wl_shm_buffer_get_format(shm_buffer)) {
      case WL_SHM_FORMAT_XRGB8888:
         pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
         gl_format = GL_BGRA_EXT;
         gl_pixel_type = GL_UNSIGNED_BYTE;
         surface->format = SURFACE_RGB;
         break;
      case WL_SHM_FORMAT_ARGB8888:
         pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
         gl_format = GL_BGRA_EXT;
         gl_pixel_type = GL_UNSIGNED_BYTE;
         surface->format = SURFACE_RGBA;
         break;
      case WL_SHM_FORMAT_RGB565:
         pitch = wl_shm_buffer_get_stride(shm_buffer) / 2;
         gl_format = GL_RGB;
         gl_pixel_type = GL_UNSIGNED_SHORT_5_6_5;
         surface->format = SURFACE_RGB;
         break;
      default:
         /* unknown shm buffer format */
         return false;
   }

   struct wlc_view *view;
   if ((view = convert_from_wlc_handle(surface->view, "view")) && view->x11.id)
      surface->format = wlc_x11_window_get_surface_format(&view->x11);

   surface_gen_textures(surface, 1);
   GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->textures[0]));
   GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, pitch));
   GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0));
   GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0));
   wl_shm_buffer_begin_access(buffer->shm_buffer);
   void *data = wl_shm_buffer_get_data(buffer->shm_buffer);
   GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, gl_format, pitch, buffer->size.h, 0, gl_format, gl_pixel_type, data));
   wl_shm_buffer_end_access(buffer->shm_buffer);
   return true;
}
QSize SurfaceBuffer::size() const
{
    if (!m_isSizeResolved) {
        if (isShmBuffer()) {
            m_size = QSize(wl_shm_buffer_get_width(m_shmBuffer), wl_shm_buffer_get_height(m_shmBuffer));
#ifdef QT_COMPOSITOR_WAYLAND_GL
        } else {
            QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration();
            m_size = hwIntegration->bufferSize(m_buffer);
#endif
        }
    }

    return m_size;
}
QImage SurfaceBuffer::image()
{
    /* This api may be available on non-shm buffer. But be sure about it's format. */
    if (!m_buffer || !isShmBuffer())
        return QImage();

    if (m_image.isNull())
    {
        const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer));
        int stride = wl_shm_buffer_get_stride(m_shmBuffer);
        int width = wl_shm_buffer_get_width(m_shmBuffer);
        int height = wl_shm_buffer_get_height(m_shmBuffer);
        m_image = QImage(data, width, height, stride, QImage::Format_ARGB32_Premultiplied);
    }

    return m_image;
}
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();
}
QImage SurfaceBuffer::image()
{
    /* This api may be available on non-shm buffer. But be sure about it's format. */
    if (!m_buffer || !isShmBuffer())
        return QImage();

    if (m_image.isNull())
    {
        const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer));
        int stride = wl_shm_buffer_get_stride(m_shmBuffer);
        int width = wl_shm_buffer_get_width(m_shmBuffer);
        int height = wl_shm_buffer_get_height(m_shmBuffer);
        QImage::Format format = QWaylandShmFormatHelper::fromWaylandShmFormat(wl_shm_format(wl_shm_buffer_get_format(m_shmBuffer)));
        m_image = QImage(data, width, height, stride, format);
    }

    return m_image;
}
Exemple #9
0
 void copyShmBufferToDisplay(wl_shm_buffer* b, int posY = 0, int posX = 0) {
     uint8_t* data = reinterpret_cast<uint8_t*>(wl_shm_buffer_get_data(b));
     int32_t w = wl_shm_buffer_get_width(b);
     int32_t h = wl_shm_buffer_get_height(b);
     int32_t lineSize = mDisplayWidth - posX;
     lineSize = w < lineSize ? w * BYTES_PER_PIXEL : lineSize * BYTES_PER_PIXEL;
     int32_t nrOfLines = (posY + h) < mDisplayHeight ? (posY + h) : mDisplayHeight;
     int32_t offsetSrc = 0;
     if (posX < 0) {
         offsetSrc -= posX * BYTES_PER_PIXEL;
         lineSize -= offsetSrc;
         posX = 0;
     }
     int32_t offsetDst = (posY * mDisplayWidth + posX) * BYTES_PER_PIXEL;
     for (int32_t y = posY; y < nrOfLines; y++) {
         blitLine(mDisplayBuffer.get() + offsetDst, data + offsetSrc, lineSize);
         offsetDst += mDisplayWidth * BYTES_PER_PIXEL;
         offsetSrc += w * BYTES_PER_PIXEL;
     }
 }
void *SurfaceBuffer::handle() const
{
    if (!m_buffer)
        return 0;

    if (!m_handle) {
        SurfaceBuffer *that = const_cast<SurfaceBuffer *>(this);
        if (isShmBuffer()) {
            const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer));
            int stride = wl_shm_buffer_get_stride(m_shmBuffer);
            int width = wl_shm_buffer_get_width(m_shmBuffer);
            int height = wl_shm_buffer_get_height(m_shmBuffer);
            QImage *image = new QImage(data,width,height,stride, QImage::Format_ARGB32_Premultiplied);
            that->m_handle = image;
#ifdef QT_COMPOSITOR_WAYLAND_GL
        } else {
            QWaylandClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration();
            that->m_handle = clientBufferIntegration->lockNativeBuffer(m_buffer, 0);
#endif
        }
    }
    return m_handle;
}
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;
}
Exemple #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;
}
Exemple #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;
         }
      }
   }
}