LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkSurface.h (source / functions) Hit Total Coverage
Test: output.info Lines: 5 13 38.5 %
Date: 2017-07-14 16:53:18 Functions: 3 8 37.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkSurface_DEFINED
       9             : #define SkSurface_DEFINED
      10             : 
      11             : #include "SkRefCnt.h"
      12             : #include "SkImage.h"
      13             : #include "SkSurfaceProps.h"
      14             : 
      15             : class SkCanvas;
      16             : class SkPaint;
      17             : class GrContext;
      18             : class GrRenderTarget;
      19             : 
      20             : /**
      21             :  *  SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be
      22             :  *  allocated either in CPU memory (a Raster surface) or on the GPU (a RenderTarget surface).
      23             :  *
      24             :  *  SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
      25             :  *  surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface).
      26             :  *
      27             :  *  SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
      28             :  *  of the requested dimensions are zero, then NULL will be returned.
      29             :  */
      30          37 : class SK_API SkSurface : public SkRefCnt {
      31             : public:
      32             :     /**
      33             :      *  Create a new surface, using the specified pixels/rowbytes as its
      34             :      *  backend.
      35             :      *
      36             :      *  If the requested surface cannot be created, or the request is not a
      37             :      *  supported configuration, NULL will be returned.
      38             :      *
      39             :      *  Callers are responsible for initialiazing the surface pixels.
      40             :      */
      41             :     static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
      42             :                                              const SkSurfaceProps* = nullptr);
      43             : 
      44             :     /**
      45             :      *  The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
      46             :      *  when the surface is deleted, and is passed the pixel memory and the specified context.
      47             :      */
      48             :     static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
      49             :                                                  void (*releaseProc)(void* pixels, void* context),
      50             :                                                  void* context, const SkSurfaceProps* = nullptr);
      51             : 
      52             :     /**
      53             :      *  Return a new surface, with the memory for the pixels automatically allocated and
      54             :      *  zero-initialized, but respecting the specified rowBytes. If rowBytes==0, then a default
      55             :      *  value will be chosen. If a non-zero rowBytes is specified, then any images snapped off of
      56             :      *  this surface (via makeImageSnapshot()) are guaranteed to have the same rowBytes.
      57             :      *
      58             :      *  If the requested surface cannot be created, or the request is not a
      59             :      *  supported configuration, NULL will be returned.
      60             :      */
      61             :     static sk_sp<SkSurface> MakeRaster(const SkImageInfo&, size_t rowBytes, const SkSurfaceProps*);
      62             : 
      63             :     /**
      64             :      *  Allocate a new surface, automatically computing the rowBytes.
      65             :      */
      66           0 :     static sk_sp<SkSurface> MakeRaster(const SkImageInfo& info,
      67             :                                        const SkSurfaceProps* props = nullptr) {
      68           0 :         return MakeRaster(info, 0, props);
      69             :     }
      70             : 
      71             :     /**
      72             :      *  Helper version of NewRaster. It creates a SkImageInfo with the
      73             :      *  specified width and height, and populates the rest of info to match
      74             :      *  pixels in SkPMColor format.
      75             :      */
      76             :     static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
      77             :                                                 const SkSurfaceProps* props = nullptr) {
      78             :         return MakeRaster(SkImageInfo::MakeN32Premul(width, height), props);
      79             :     }
      80             : 
      81             :     /**
      82             :      *  Used to wrap a pre-existing backend 3D API texture as a SkSurface. The kRenderTarget flag
      83             :      *  must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership
      84             :      *  of the texture and the client must ensure the texture is valid for the lifetime of the
      85             :      *  SkSurface.
      86             :      */
      87             :     static sk_sp<SkSurface> MakeFromBackendTexture(GrContext*, const GrBackendTextureDesc&,
      88             :                                                    sk_sp<SkColorSpace>, const SkSurfaceProps*);
      89             : 
      90             :     /**
      91             :      *  Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume
      92             :      *  ownership of the render target and the client must ensure the render target is valid for the
      93             :      *  lifetime of the SkSurface.
      94             :      */
      95             :     static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext*,
      96             :                                                         const GrBackendRenderTargetDesc&,
      97             :                                                         sk_sp<SkColorSpace>,
      98             :                                                         const SkSurfaceProps*);
      99             : 
     100             :     /**
     101             :      *  Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat the texture as
     102             :      *  a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
     103             :      *  the associated render target objects (but not the provided texture). The kRenderTarget flag
     104             :      *  must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership
     105             :      *  of the texture and the client must ensure the texture is valid for the lifetime of the
     106             :      *  SkSurface.
     107             :      */
     108             :     static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(
     109             :         GrContext*, const GrBackendTextureDesc&, sk_sp<SkColorSpace>, const SkSurfaceProps*);
     110             : 
     111             :     /**
     112             :      * Legacy versions of the above factories, without color space support. These create "legacy"
     113             :      * surfaces that operate without gamma correction or color management.
     114             :      */
     115             :     static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
     116             :                                                    const SkSurfaceProps* props) {
     117             :         return MakeFromBackendTexture(ctx, desc, nullptr, props);
     118             :     }
     119             : 
     120             :     static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* ctx,
     121             :                                                         const GrBackendRenderTargetDesc& desc,
     122             :                                                         const SkSurfaceProps* props) {
     123             :         return MakeFromBackendRenderTarget(ctx, desc, nullptr, props);
     124             :     }
     125             : 
     126             :     static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(
     127             :             GrContext* ctx, const GrBackendTextureDesc& desc, const SkSurfaceProps* props) {
     128             :         return MakeFromBackendTextureAsRenderTarget(ctx, desc, nullptr, props);
     129             :     }
     130             : 
     131             : 
     132             :     /**
     133             :      *  Return a new surface whose contents will be drawn to an offscreen
     134             :      *  render target, allocated by the surface.
     135             :      */
     136             :     static sk_sp<SkSurface> MakeRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
     137             :                                              int sampleCount, GrSurfaceOrigin,
     138             :                                              const SkSurfaceProps*);
     139             : 
     140             :     static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
     141             :                                              const SkImageInfo& info, int sampleCount,
     142             :                                              const SkSurfaceProps* props) {
     143             :         return MakeRenderTarget(context, budgeted, info, sampleCount,
     144             :                                 kBottomLeft_GrSurfaceOrigin, props);
     145             :     }
     146             : 
     147           0 :     static sk_sp<SkSurface> MakeRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) {
     148           0 :         if (!info.width() || !info.height()) {
     149           0 :             return nullptr;
     150             :         }
     151           0 :         return MakeRenderTarget(gr, b, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr);
     152             :     }
     153             : 
     154           0 :     int width() const { return fWidth; }
     155           0 :     int height() const { return fHeight; }
     156             : 
     157             :     /**
     158             :      *  Returns a unique non-zero, unique value identifying the content of this
     159             :      *  surface. Each time the content is changed changed, either by drawing
     160             :      *  into this surface, or explicitly calling notifyContentChanged()) this
     161             :      *  method will return a new value.
     162             :      *
     163             :      *  If this surface is empty (i.e. has a zero-dimention), this will return
     164             :      *  0.
     165             :      */
     166             :     uint32_t generationID();
     167             : 
     168             :     /**
     169             :      *  Modes that can be passed to notifyContentWillChange
     170             :      */
     171             :     enum ContentChangeMode {
     172             :         /**
     173             :          *  Use this mode if it is known that the upcoming content changes will
     174             :          *  clear or overwrite prior contents, thus making them discardable.
     175             :          */
     176             :         kDiscard_ContentChangeMode,
     177             :         /**
     178             :          *  Use this mode if prior surface contents need to be preserved or
     179             :          *  if in doubt.
     180             :          */
     181             :         kRetain_ContentChangeMode,
     182             :     };
     183             : 
     184             :     /**
     185             :      *  Call this if the contents are about to change. This will (lazily) force a new
     186             :      *  value to be returned from generationID() when it is called next.
     187             :      *
     188             :      *  CAN WE DEPRECATE THIS?
     189             :      */
     190             :     void notifyContentWillChange(ContentChangeMode mode);
     191             : 
     192             :     enum BackendHandleAccess {
     193             :         kFlushRead_BackendHandleAccess,     //!< caller may read from the backend object
     194             :         kFlushWrite_BackendHandleAccess,    //!< caller may write to the backend object
     195             :         kDiscardWrite_BackendHandleAccess,  //!< caller must over-write the entire backend object
     196             :     };
     197             : 
     198             :     /*
     199             :      * These are legacy aliases which will be removed soon
     200             :      */
     201             :     static const BackendHandleAccess kFlushRead_TextureHandleAccess =
     202             :             kFlushRead_BackendHandleAccess;
     203             :     static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
     204             :             kFlushWrite_BackendHandleAccess;
     205             :     static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
     206             :             kDiscardWrite_BackendHandleAccess;
     207             : 
     208             : 
     209             :     /**
     210             :      *  Retrieves the backend API handle of the texture used by this surface, or 0 if the surface
     211             :      *  is not backed by a GPU texture.
     212             :      *
     213             :      *  The returned texture-handle is only valid until the next draw-call into the surface,
     214             :      *  or the surface is deleted.
     215             :      */
     216             :     GrBackendObject getTextureHandle(BackendHandleAccess);
     217             : 
     218             :     /**
     219             :      *  Retrieves the backend API handle of the RenderTarget backing this surface.  Callers must
     220             :      *  ensure this function returns 'true' or else the GrBackendObject will be invalid
     221             :      *
     222             :      *  In OpenGL this will return the FramebufferObject ID.
     223             :      */
     224             :     bool getRenderTargetHandle(GrBackendObject*, BackendHandleAccess);
     225             : 
     226             :     /**
     227             :      *  Return a canvas that will draw into this surface. This will always
     228             :      *  return the same canvas for a given surface, and is manged/owned by the
     229             :      *  surface. It should not be used when its parent surface has gone out of
     230             :      *  scope.
     231             :      */
     232             :     SkCanvas* getCanvas();
     233             : 
     234             :     /**
     235             :      *  Return a new surface that is "compatible" with this one, in that it will
     236             :      *  efficiently be able to be drawn into this surface. Typical calling
     237             :      *  pattern:
     238             :      *
     239             :      *  SkSurface* A = SkSurface::New...();
     240             :      *  SkCanvas* canvasA = surfaceA->newCanvas();
     241             :      *  ...
     242             :      *  SkSurface* surfaceB = surfaceA->newSurface(...);
     243             :      *  SkCanvas* canvasB = surfaceB->newCanvas();
     244             :      *  ... // draw using canvasB
     245             :      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
     246             :      */
     247             :     sk_sp<SkSurface> makeSurface(const SkImageInfo&);
     248             : 
     249             :     /**
     250             :      *  Returns an image of the current state of the surface pixels up to this
     251             :      *  point. Subsequent changes to the surface (by drawing into its canvas)
     252             :      *  will not be reflected in this image. For the GPU-backend, the budgeting
     253             :      *  decision for the snapped image will match that of the surface.
     254             :      */
     255             :     sk_sp<SkImage> makeImageSnapshot();
     256             : 
     257             :     /**
     258             :      *  Though the caller could get a snapshot image explicitly, and draw that,
     259             :      *  it seems that directly drawing a surface into another canvas might be
     260             :      *  a common pattern, and that we could possibly be more efficient, since
     261             :      *  we'd know that the "snapshot" need only live until we've handed it off
     262             :      *  to the canvas.
     263             :      */
     264             :     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
     265             : 
     266             :     /**
     267             :      *  If the surface has direct access to its pixels (i.e. they are in local
     268             :      *  RAM) return true, and if not null, set the pixmap parameter to point to the information
     269             :      *  about the surface's pixels. The pixel address in the pixmap is only valid while
     270             :      *  the surface object is in scope, and no API call is made on the surface
     271             :      *  or its canvas.
     272             :      *
     273             :      *  On failure, returns false and the pixmap parameter is ignored.
     274             :      */
     275             :     bool peekPixels(SkPixmap*);
     276             : 
     277             :     /**
     278             :      *  Copy the pixels from the surface into the specified buffer (pixels + rowBytes),
     279             :      *  converting them into the requested format (dstInfo). The surface pixels are read
     280             :      *  starting at the specified (srcX,srcY) location.
     281             :      *
     282             :      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
     283             :      *
     284             :      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
     285             :      *
     286             :      *  srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
     287             :      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
     288             :      *  corresponding src pixels, performing any colortype/alphatype transformations needed
     289             :      *  (in the case where the src and dst have different colortypes or alphatypes).
     290             :      *
     291             :      *  This call can fail, returning false, for several reasons:
     292             :      *  - If srcR does not intersect the surface bounds.
     293             :      *  - If the requested colortype/alphatype cannot be converted from the surface's types.
     294             :      */
     295             :     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
     296             :                     int srcX, int srcY);
     297             : 
     298          63 :     const SkSurfaceProps& props() const { return fProps; }
     299             : 
     300             :     /**
     301             :      * Issue any pending surface IO to the current backend 3D API and resolve any surface MSAA.
     302             :      */
     303             :     void prepareForExternalIO();
     304             : 
     305             : protected:
     306             :     SkSurface(int width, int height, const SkSurfaceProps*);
     307             :     SkSurface(const SkImageInfo&, const SkSurfaceProps*);
     308             : 
     309             :     // called by subclass if their contents have changed
     310         452 :     void dirtyGenerationID() {
     311         452 :         fGenerationID = 0;
     312         452 :     }
     313             : 
     314             : private:
     315             :     const SkSurfaceProps fProps;
     316             :     const int            fWidth;
     317             :     const int            fHeight;
     318             :     uint32_t             fGenerationID;
     319             : 
     320             :     typedef SkRefCnt INHERITED;
     321             : };
     322             : 
     323             : #endif

Generated by: LCOV version 1.13