working on SkImage docs

also fix minor break in SkSurface

TBR=caryclark@google.com
Docs-Preview: https://skia.org/?cl=105021
Bug: skia:
Change-Id: I0cfc01ab5ba4df13a9e84f8dd2904d32e5726a5b
Reviewed-on: https://skia-review.googlesource.com/105021
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkImage_Reference.bmh b/docs/SkImage_Reference.bmh
index d933a07..dc4d4ef 100644
--- a/docs/SkImage_Reference.bmh
+++ b/docs/SkImage_Reference.bmh
@@ -418,7 +418,7 @@
 int x = 0;
 for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
     sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,
-           origin, kOpaque_SkAlphaType, nullptr);
+           origin, kN32_SkColorType, kOpaque_SkAlphaType, nullptr);
     canvas->drawImage(image, x, 0);
 x += 512;
 }
@@ -817,7 +817,7 @@
 # currently uncalled by any test or client ##
 #Bug 7424
 
-#Enum BitDepth
+#EnumClass BitDepth
 
 #Code
     enum class BitDepth {
@@ -838,7 +838,7 @@
 
 #SeeAlso MakeFromPicture
 
-#Enum ##
+#EnumClass ##
 
 # ------------------------------------------------------------------------------
 
@@ -2001,7 +2001,7 @@
     drawImage(textureImage, "backEndTexture");
 ##
 
-#SeeAlso incomplete
+#SeeAlso makeTextureImage makeRasterImage MakeBackendTextureFromSkImage
 
 #Method ##
 
@@ -2064,19 +2064,17 @@
 Returns nullptr if Image could not be created. If nullptr is returned, outSubset
 and offset are undefined.
 
-makeWithFilter is optimized to support Image backed by GPU_Texture drawn in an
-animation with SkImageFilter that vary in size from one frame to the next. The
-created Image is drawn at an increased size so that GPU_Texture can be reused
-with different sized effects. outSubset describes the valid bounds of GPU_Texture
-returned. The returned Image may be much larger than required for the filter.
-offset translates the returned Image to keep subsequent animation frames
-aligned with respect to each other.
+Useful for animation of SkImageFilter that varies size from frame to frame.
+Returned Image is created larger than required by filter so that GPU_Texture
+can be reused with different sized effects. outSubset describes the valid bounds
+of GPU_Texture returned. offset translates the returned Image to keep subsequent
+animation frames aligned with respect to each other.
 
 #Param filter  how Image is sampled when transformed ##
-#Param subset  incomplete ##
-#Param clipBounds  incomplete ##
-#Param outSubset  incomplete ##
-#Param offset  incomplete ##
+#Param subset  bounds of Image processed by filter ##
+#Param clipBounds  expected bounds of filtered Image ##
+#Param outSubset  storage for returned Image bounds ##
+#Param offset  storage for returned Image translation ##
 
 #Return filtered Image, or nullptr ##
 
@@ -2109,7 +2107,7 @@
     canvas->drawRect(SkRect::MakeFromIRect(outSubset), paint);
 ##
 
-#SeeAlso SkPaint::setImageFilter
+#SeeAlso makeShader SkPaint::setImageFilter
 
 #Method ##
 
@@ -2155,64 +2153,86 @@
 #In Constructor
 #Line # creates GPU_Texture from Image ##
 
-Creates a GrBackendTexture from the provided SkImage. Returns true on success. The
-GrBackendTexture and BackendTextureReleaseProc are populated on success. It is the callers
-responsibility to call the BackendTextureReleaseProc once they have deleted the texture.
-Note that the BackendTextureReleaseProc allows Skia to clean up auxiliary data related
-to the GrBackendTexture, and is not a substitute for the client deleting the GrBackendTexture
-themselves.
+Creates a GrBackendTexture from the provided SkImage. Returns true and
+stores result in backendTexture and backendTextureReleaseProc if
+texture is created; otherwise, returns false and leaves
+backendTexture and backendTextureReleaseProc unmodified.
 
-If image is both texture backed and singly referenced; that is, its only
-reference was transferred using std::move(): image is returned in backendTexture
-without conversion or making a copy. 
+Call backendTextureReleaseProc after deleting backendTexture.
+backendTextureReleaseProc cleans up auxiliary data related to returned
+backendTexture. The caller must delete returned backendTexture after use.
 
-If Image is not texture backed, this function returns texture with Image
-contents.
+If Image is both texture backed and singly referenced, image is returned in
+backendTexture without conversion or making a copy. Image is singly referenced
+if its was transferred solely using std::move().
+
+If Image is not texture backed, returns texture with Image contents.
 
 #Param context  GPU_Context ##
-#Param image  incomplete ##
-#Param backendTexture  incomplete ##
-#Param backendTextureReleaseProc  incomplete ##
+#Param image  Image used for texture ##
+#Param backendTexture  storage for backend texture ##
+#Param backendTextureReleaseProc  storage for clean up function ##
 
-#Return incomplete ##
+#Return true if backend texture was created ##
 
 #Example
-// incomplete
+#Platform gpu
+#Height 64
+#Function
+static sk_sp<SkImage> create_gpu_image(GrContext* grContext) {

+    const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);

+    auto surface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));

+    SkCanvas* canvas = surface->getCanvas();

+    canvas->clear(SK_ColorWHITE);

+    SkPaint paint;

+    paint.setColor(SK_ColorBLACK);

+    canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);

+    return surface->makeImageSnapshot();

+}

+##

+

+void draw(SkCanvas* canvas) {    

+    GrContext* grContext = canvas->getGrContext();

+    if (!grContext) {

+        return;

+    }

+    sk_sp<SkImage> backEndImage = create_gpu_image(grContext);

+    canvas->drawImage(backEndImage, 0, 0);

+    GrBackendTexture texture;

+    SkImage::BackendTextureReleaseProc proc;

+    if (!SkImage::MakeBackendTextureFromSkImage(grContext, std::move(backEndImage),

+            &texture, &proc)) {

+        return;

+    }

+    sk_sp<SkImage> i2 = SkImage::MakeFromTexture(grContext, texture, kTopLeft_GrSurfaceOrigin,

+            kN32_SkColorType, kOpaque_SkAlphaType, nullptr);

+    canvas->drawImage(i2, 30, 30);

+}
 ##
 
-#SeeAlso incomplete
+#SeeAlso MakeFromTexture makeTextureImage
 
 #Method ##
 
 # ------------------------------------------------------------------------------
 
 #Enum LegacyBitmapMode
-
+#Deprecated soon
 #Code
     enum LegacyBitmapMode {
         kRO_LegacyBitmapMode,
-        kRW_LegacyBitmapMode,
     };
 ##
 
-Helper functions to convert to SkBitmap
-
 #Const kRO_LegacyBitmapMode 0
+Returned bitmap is read-only and immutable.
 ##
-#Const kRW_LegacyBitmapMode 1
-##
-
-#Example
-// incomplete
-##
-
-#SeeAlso incomplete
 
 #Enum ##
 
 # ------------------------------------------------------------------------------
 
-#Method bool asLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode legacyBitmapMode) const
+#Method bool asLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const
 #In Constructor
 #Line # returns as Raster_Bitmap ##
 Creates raster Bitmap with same pixels as Image. If legacyBitmapMode is
@@ -2221,15 +2241,30 @@
 Bitmap write did not succeed.
 
 #Param bitmap  storage for legacy Bitmap ##
-#Param legacyBitmapMode  one of: kRO_LegacyBitmapMode, kRW_LegacyBitmapMode ##
+#Param legacyBitmapMode  to be deprecated ##
 
 #Return true if Bitmap was created ##
 
 #Example
-// incomplete
+#Image 4
+#Platform gpu
+    SkBitmap bitImage;

+    if (image->asLegacyBitmap(&bitImage, SkImage::kRO_LegacyBitmapMode)) {

+        canvas->drawBitmap(bitImage, 0, 0);

+    }

+    GrContext* grContext = canvas->getGrContext();

+    if (!grContext) {

+        return;

+    }

+    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(grContext, backEndTexture,

+                                kTopLeft_GrSurfaceOrigin, kOpaque_SkAlphaType, nullptr));

+    canvas->drawImage(textureImage, 45, 45);

+    if (textureImage->asLegacyBitmap(&bitImage, SkImage::kRO_LegacyBitmapMode)) {

+        canvas->drawBitmap(bitImage, 90, 90);

+    }

 ##
 
-#SeeAlso incomplete
+#SeeAlso MakeRasterData makeRasterImage makeNonTextureImage
 
 #Method ##
 
diff --git a/docs/SkPaint_Reference.bmh b/docs/SkPaint_Reference.bmh
index 94e9798..c35f021 100644
--- a/docs/SkPaint_Reference.bmh
+++ b/docs/SkPaint_Reference.bmh
@@ -1968,7 +1968,7 @@
 #Const kStroke_Style 1
     Set to stroke geometry.
     Applies to Rect, Region, Round_Rect, Arcs, Circles, Ovals, Path, and Text. 
-    Arcs, Lines, and Points, are always drawn as if kStroke_Style is set,
+    Arcs, Lines, and points, are always drawn as if kStroke_Style is set,
     and ignore the set Style.
     The stroke construction is unaffected by the Path_Fill_Type.
 ##
diff --git a/docs/SkSurface_Reference.bmh b/docs/SkSurface_Reference.bmh
index 7935bfe..16785b4 100644
--- a/docs/SkSurface_Reference.bmh
+++ b/docs/SkSurface_Reference.bmh
@@ -1582,11 +1582,16 @@
 # ------------------------------------------------------------------------------
 
 #Method void writePixels(const SkPixmap& src, int dstX, int dstY)
-
+#In Pixels
+#Line # copies Rect of pixels ##
 Copies Rect of pixels from the src Pixmap to the Surface.
 
 Source Rect corners are (0, 0) and (src.width(), src.height()).
-Destination Rect corners are (dstX, dstY) and (dstX + Surface width(), dstY + Surface height()).
+Destination Rect corners are (dstX, dstY) and 
+#Formula
+(dstX + Surface width(), dstY + Surface height())
+##
+.
 Copies each readable pixel intersecting both rectangles, without scaling,
 converting to Surface colorType() and Surface alphaType() if required.
 
@@ -1595,7 +1600,7 @@
 #Param dstY x position relative to Surface to begin copy; may be negative ##
 
 #Example
-    // todo
+    // incomplete
 ##
 
 #SeeAlso readPixels peekPixels
@@ -1609,7 +1614,11 @@
 Copies Rect of pixels from the src Bitmap to the Surface.
 
 Source Rect corners are (0, 0) and (src.width(), src.height()).
-Destination Rect corners are (dstX, dstY) and (dstX + Surface width(), dstY + Surface height()).
+Destination Rect corners are (dstX, dstY) and
+#Formula
+(dstX + Surface width(), dstY + Surface height())
+##
+.
 Copies each readable pixel intersecting both rectangles, without scaling,
 converting to Surface colorType() and Surface alphaType() if required.
 
@@ -1618,7 +1627,7 @@
 #Param dstY x position relative to Surface to begin copy; may be negative ##
 
 #Example
-    // todo
+    // incomplete
 ##
 
 #SeeAlso readPixels peekPixels
diff --git a/docs/status.json b/docs/status.json
index 09a0b80..7b8b7f7 100644
--- a/docs/status.json
+++ b/docs/status.json
@@ -4,6 +4,7 @@
             "core": [

                 "SkBitmap.h",

                 "SkCanvas.h",

+                "SkImage.h",

                 "SkMatrix.h",

                 "SkPaint.h",

                 "SkPath.h",

@@ -20,6 +21,7 @@
             "SkPaint_Reference.bmh",

             "SkPoint_Reference.bmh",

             "SkIRect_Reference.bmh",

+            "SkImage_Reference.bmh",

             "SkPath_Reference.bmh",

             "SkRect_Reference.bmh",

             "SkBitmap_Reference.bmh",

@@ -33,12 +35,10 @@
     "InProgress": {

         "include": {

             "core": [

-                "SkImage.h",

                 "SkImageInfo.h"

             ]

         },

         "docs": [

-            "SkImage_Reference.bmh",

             "SkImageInfo_Reference.bmh",

             "overview.bmh",

             "usingBookmaker.bmh"

diff --git a/site/user/api/SkImage_Reference.md b/site/user/api/SkImage_Reference.md
index 11298c3..d37b4fa 100644
--- a/site/user/api/SkImage_Reference.md
+++ b/site/user/api/SkImage_Reference.md
@@ -480,7 +480,7 @@
 
 ### Example
 
-<div><fiddle-embed name="d5e43961a54548f445eece91d517381c" gpu="true"><div>A back-end texture has been created and uploaded to the GPU outside of this example.</div></fiddle-embed></div>
+<div><fiddle-embed name="fdc498de45b53569743ec13012bf476c" gpu="true"><div>A back-end texture has been created and uploaded to the GPU outside of this example.</div></fiddle-embed></div>
 
 ### See Also
 
@@ -736,8 +736,8 @@
 <table>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_context"> <code><strong>context </strong></code> </a></td> <td>
 <a href="undocumented#GPU_Context">GPU Context</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_yuvColorSpace"> <code><strong>yuvColorSpace </strong></code> </a></td> <td>
-one of: <a href="undocumented#YUV_ColorSpace">kJPEG SkYUVColorSpace</a>, <a href="undocumented#YUV_ColorSpace">kRec601 SkYUVColorSpace</a>,
-<a href="undocumented#YUV_ColorSpace">kRec709 SkYUVColorSpace</a></td>
+one of: <a href="SkImageInfo_Reference#SkYUVColorSpace">kJPEG SkYUVColorSpace</a>, <a href="SkImageInfo_Reference#SkYUVColorSpace">kRec601 SkYUVColorSpace</a>,
+<a href="SkImageInfo_Reference#SkYUVColorSpace">kRec709 SkYUVColorSpace</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_yuvTextureHandles"> <code><strong>yuvTextureHandles </strong></code> </a></td> <td>
 array of YUV textures on GPU</td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_yuvSizes"> <code><strong>yuvSizes </strong></code> </a></td> <td>
@@ -780,8 +780,8 @@
 <table>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_2_context"> <code><strong>context </strong></code> </a></td> <td>
 <a href="undocumented#GPU_Context">GPU Context</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_2_yuvColorSpace"> <code><strong>yuvColorSpace </strong></code> </a></td> <td>
-one of: <a href="undocumented#YUV_ColorSpace">kJPEG SkYUVColorSpace</a>, <a href="undocumented#YUV_ColorSpace">kRec601 SkYUVColorSpace</a>,
-<a href="undocumented#YUV_ColorSpace">kRec709 SkYUVColorSpace</a></td>
+one of: <a href="SkImageInfo_Reference#SkYUVColorSpace">kJPEG SkYUVColorSpace</a>, <a href="SkImageInfo_Reference#SkYUVColorSpace">kRec601 SkYUVColorSpace</a>,
+<a href="SkImageInfo_Reference#SkYUVColorSpace">kRec709 SkYUVColorSpace</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_2_yuvTextureHandles"> <code><strong>yuvTextureHandles </strong></code> </a></td> <td>
 array of YUV textures on GPU</td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromYUVTexturesCopy_2_yuvSizes"> <code><strong>yuvSizes </strong></code> </a></td> <td>
@@ -827,8 +827,8 @@
 <table>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_context"> <code><strong>context </strong></code> </a></td> <td>
 <a href="undocumented#GPU_Context">GPU Context</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_yuvColorSpace"> <code><strong>yuvColorSpace </strong></code> </a></td> <td>
-one of: <a href="undocumented#YUV_ColorSpace">kJPEG SkYUVColorSpace</a>, <a href="undocumented#YUV_ColorSpace">kRec601 SkYUVColorSpace</a>,
-<a href="undocumented#YUV_ColorSpace">kRec709 SkYUVColorSpace</a></td>
+one of: <a href="SkImageInfo_Reference#SkYUVColorSpace">kJPEG SkYUVColorSpace</a>, <a href="SkImageInfo_Reference#SkYUVColorSpace">kRec601 SkYUVColorSpace</a>,
+<a href="SkImageInfo_Reference#SkYUVColorSpace">kRec709 SkYUVColorSpace</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_nv12TextureHandles"> <code><strong>nv12TextureHandles </strong></code> </a></td> <td>
 array of YUV textures on GPU</td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_nv12Sizes"> <code><strong>nv12Sizes </strong></code> </a></td> <td>
@@ -873,8 +873,8 @@
 <table>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_2_context"> <code><strong>context </strong></code> </a></td> <td>
 <a href="undocumented#GPU_Context">GPU Context</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_2_yuvColorSpace"> <code><strong>yuvColorSpace </strong></code> </a></td> <td>
-one of: <a href="undocumented#YUV_ColorSpace">kJPEG SkYUVColorSpace</a>, <a href="undocumented#YUV_ColorSpace">kRec601 SkYUVColorSpace</a>,
-<a href="undocumented#YUV_ColorSpace">kRec709 SkYUVColorSpace</a></td>
+one of: <a href="SkImageInfo_Reference#SkYUVColorSpace">kJPEG SkYUVColorSpace</a>, <a href="SkImageInfo_Reference#SkYUVColorSpace">kRec601 SkYUVColorSpace</a>,
+<a href="SkImageInfo_Reference#SkYUVColorSpace">kRec709 SkYUVColorSpace</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_2_nv12TextureHandles"> <code><strong>nv12TextureHandles </strong></code> </a></td> <td>
 array of YUV textures on GPU</td>
   </tr>  <tr>    <td><a name="SkImage_MakeFromNV12TexturesCopy_2_nv12Sizes"> <code><strong>nv12Sizes </strong></code> </a></td> <td>
@@ -900,18 +900,18 @@
 
 <pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
 enum class <a href="#SkImage_BitDepth">BitDepth</a> {
-<a href="#SkImage_kU8">kU8</a>,
-<a href="#SkImage_kF16">kF16</a>,
+<a href="#SkImage_BitDepth_kU8">kU8</a>,
+<a href="#SkImage_BitDepth_kF16">kF16</a>,
 };</pre>
 
 ### Constants
 
 <table>
   <tr>
-    <td><a name="SkImage_kU8"> <code><strong>SkImage::kU8 </strong></code> </a></td><td>0</td><td>Use 8 bits per <a href="#ARGB">Color ARGB</a> component using unsigned integer format.</td>
+    <td><a name="SkImage_BitDepth_kU8"> <code><strong>SkImage::BitDepth::kU8 </strong></code> </a></td><td>0</td><td>Use 8 bits per <a href="#ARGB">Color ARGB</a> component using unsigned integer format.</td>
   </tr>
   <tr>
-    <td><a name="SkImage_kF16"> <code><strong>SkImage::kF16 </strong></code> </a></td><td>1</td><td>Use 16 bits per <a href="#ARGB">Color ARGB</a> component using half-precision floating point format.</td>
+    <td><a name="SkImage_BitDepth_kF16"> <code><strong>SkImage::BitDepth::kF16 </strong></code> </a></td><td>1</td><td>Use 16 bits per <a href="#ARGB">Color ARGB</a> component using half-precision floating point format.</td>
   </tr>
 </table>
 
@@ -1984,7 +1984,7 @@
 
 ### See Also
 
-incomplete
+<a href="#SkImage_makeTextureImage">makeTextureImage</a> <a href="#SkImage_makeRasterImage">makeRasterImage</a> <a href="#SkImage_MakeBackendTextureFromSkImage">MakeBackendTextureFromSkImage</a>
 
 ---
 
@@ -2032,26 +2032,24 @@
 Returns nullptr if <a href="#Image">Image</a> could not be created. If nullptr is returned, <a href="#SkImage_makeWithFilter_outSubset">outSubset</a>
 and <a href="#SkImage_makeWithFilter_offset">offset</a> are undefined.
 
-<a href="#SkImage_makeWithFilter">makeWithFilter</a> is optimized to support <a href="#Image">Image</a> backed by <a href="undocumented#GPU_Texture">GPU Texture</a> drawn in an
-animation with <a href="undocumented#SkImageFilter">SkImageFilter</a> that vary in size from one frame to the next. The
-created <a href="#Image">Image</a> is drawn at an increased size so that <a href="undocumented#GPU_Texture">GPU Texture</a> can be reused
-with different sized effects. <a href="#SkImage_makeWithFilter_outSubset">outSubset</a> describes the valid bounds of <a href="undocumented#GPU_Texture">GPU Texture</a>
-returned. The returned <a href="#Image">Image</a> may be much larger than required for the <a href="#SkImage_makeWithFilter_filter">filter</a>.
-<a href="#SkImage_makeWithFilter_offset">offset</a> translates the returned <a href="#Image">Image</a> to keep subsequent animation frames
-aligned with respect to each other.
+Useful for animation of <a href="undocumented#SkImageFilter">SkImageFilter</a> that varies size from frame to frame.
+Returned <a href="#Image">Image</a> is created larger than required by <a href="#SkImage_makeWithFilter_filter">filter</a> so that <a href="undocumented#GPU_Texture">GPU Texture</a>
+can be reused with different sized effects. <a href="#SkImage_makeWithFilter_outSubset">outSubset</a> describes the valid bounds
+of <a href="undocumented#GPU_Texture">GPU Texture</a> returned. <a href="#SkImage_makeWithFilter_offset">offset</a> translates the returned <a href="#Image">Image</a> to keep subsequent
+animation frames aligned with respect to each other.
 
 ### Parameters
 
 <table>  <tr>    <td><a name="SkImage_makeWithFilter_filter"> <code><strong>filter </strong></code> </a></td> <td>
 how <a href="#Image">Image</a> is sampled when transformed</td>
   </tr>  <tr>    <td><a name="SkImage_makeWithFilter_subset"> <code><strong>subset </strong></code> </a></td> <td>
-incomplete</td>
+bounds of <a href="#Image">Image</a> processed by <a href="#SkImage_makeWithFilter_filter">filter</a></td>
   </tr>  <tr>    <td><a name="SkImage_makeWithFilter_clipBounds"> <code><strong>clipBounds </strong></code> </a></td> <td>
-incomplete</td>
+expected bounds of filtered <a href="#Image">Image</a></td>
   </tr>  <tr>    <td><a name="SkImage_makeWithFilter_outSubset"> <code><strong>outSubset </strong></code> </a></td> <td>
-incomplete</td>
+storage for returned <a href="#Image">Image</a> bounds</td>
   </tr>  <tr>    <td><a name="SkImage_makeWithFilter_offset"> <code><strong>offset </strong></code> </a></td> <td>
-incomplete</td>
+storage for returned <a href="#Image">Image</a> translation</td>
   </tr>
 </table>
 
@@ -2066,7 +2064,7 @@
 
 ### See Also
 
-<a href="#SkPaint_setImageFilter">SkPaint::setImageFilter</a>
+<a href="#SkImage_makeShader">makeShader</a><sup><a href="#SkImage_makeShader_2">[2]</a></sup> <a href="#SkPaint_setImageFilter">SkPaint::setImageFilter</a>
 
 ---
 
@@ -2110,83 +2108,71 @@
                                           BackendTextureReleaseProc* backendTextureReleaseProc)
 </pre>
 
-Creates a <a href="undocumented#GrBackendTexture">GrBackendTexture</a> from the provided <a href="#SkImage">SkImage</a>. Returns true on success. The
-<a href="undocumented#GrBackendTexture">GrBackendTexture</a> and <a href="#SkImage_BackendTextureReleaseProc">BackendTextureReleaseProc</a> are populated on success. It is the callers
-responsibility to call the <a href="#SkImage_BackendTextureReleaseProc">BackendTextureReleaseProc</a> once they have deleted the texture.
-Note that the <a href="#SkImage_BackendTextureReleaseProc">BackendTextureReleaseProc</a> allows Skia to clean up auxiliary data related
-to the <a href="undocumented#GrBackendTexture">GrBackendTexture</a>, and is not a substitute for the client deleting the <a href="undocumented#GrBackendTexture">GrBackendTexture</a>
-themselves.
+Creates a <a href="undocumented#GrBackendTexture">GrBackendTexture</a> from the provided <a href="#SkImage">SkImage</a>. Returns true and
+stores result in <a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a> and <a href="#SkImage_MakeBackendTextureFromSkImage_backendTextureReleaseProc">backendTextureReleaseProc</a> if
+texture is created; otherwise, returns false and leaves
+<a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a> and <a href="#SkImage_MakeBackendTextureFromSkImage_backendTextureReleaseProc">backendTextureReleaseProc</a> unmodified.
 
-If <a href="#SkImage_MakeBackendTextureFromSkImage_image">image</a> is both texture backed and singly referenced; that is, its only
-reference was transferred using std::move(): <a href="#SkImage_MakeBackendTextureFromSkImage_image">image</a> is returned in <a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a>
-without conversion or making a copy.
+Call <a href="#SkImage_MakeBackendTextureFromSkImage_backendTextureReleaseProc">backendTextureReleaseProc</a> after deleting <a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a>.
+<a href="#SkImage_MakeBackendTextureFromSkImage_backendTextureReleaseProc">backendTextureReleaseProc</a> cleans up auxiliary data related to returned
+<a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a>. The caller must delete returned <a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a> after use.
 
-If <a href="#Image">Image</a> is not texture backed, this function returns texture with <a href="#Image">Image</a>
-contents.
+If <a href="#Image">Image</a> is both texture backed and singly referenced, <a href="#SkImage_MakeBackendTextureFromSkImage_image">image</a> is returned in
+<a href="#SkImage_MakeBackendTextureFromSkImage_backendTexture">backendTexture</a> without conversion or making a copy. <a href="#Image">Image</a> is singly referenced
+if its was transferred solely using std::move().
+
+If <a href="#Image">Image</a> is not texture backed, returns texture with <a href="#Image">Image</a> contents.
 
 ### Parameters
 
 <table>  <tr>    <td><a name="SkImage_MakeBackendTextureFromSkImage_context"> <code><strong>context </strong></code> </a></td> <td>
 <a href="undocumented#GPU_Context">GPU Context</a></td>
   </tr>  <tr>    <td><a name="SkImage_MakeBackendTextureFromSkImage_image"> <code><strong>image </strong></code> </a></td> <td>
-incomplete</td>
+<a href="#Image">Image</a> used for texture</td>
   </tr>  <tr>    <td><a name="SkImage_MakeBackendTextureFromSkImage_backendTexture"> <code><strong>backendTexture </strong></code> </a></td> <td>
-incomplete</td>
+storage for backend texture</td>
   </tr>  <tr>    <td><a name="SkImage_MakeBackendTextureFromSkImage_backendTextureReleaseProc"> <code><strong>backendTextureReleaseProc </strong></code> </a></td> <td>
-incomplete</td>
+storage for clean up function</td>
   </tr>
 </table>
 
 ### Return Value
 
-incomplete
+true if backend texture was created
 
 ### Example
 
-<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+<div><fiddle-embed name="98e70337c2964abd2624239d28bbecd7" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
-incomplete
+<a href="#SkImage_MakeFromTexture">MakeFromTexture</a><sup><a href="#SkImage_MakeFromTexture_2">[2]</a></sup><sup><a href="#SkImage_MakeFromTexture_3">[3]</a></sup><sup><a href="#SkImage_MakeFromTexture_4">[4]</a></sup> <a href="#SkImage_makeTextureImage">makeTextureImage</a>
 
 ---
 
 ## <a name="SkImage_LegacyBitmapMode"></a> Enum SkImage::LegacyBitmapMode
 
+soon
+
 <pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
 enum <a href="#SkImage_LegacyBitmapMode">LegacyBitmapMode</a> {
 <a href="#SkImage_kRO_LegacyBitmapMode">kRO LegacyBitmapMode</a>,
-<a href="#SkImage_kRW_LegacyBitmapMode">kRW LegacyBitmapMode</a>,
 };</pre>
 
-Helper functions to convert to <a href="SkBitmap_Reference#SkBitmap">SkBitmap</a>
-
 ### Constants
 
 <table>
   <tr>
-    <td><a name="SkImage_kRO_LegacyBitmapMode"> <code><strong>SkImage::kRO_LegacyBitmapMode </strong></code> </a></td><td>0</td><td></td>
+    <td><a name="SkImage_kRO_LegacyBitmapMode"> <code><strong>SkImage::kRO_LegacyBitmapMode </strong></code> </a></td><td>0</td><td>Returned bitmap is read-only and immutable.</td>
   </tr>
-  <tr>
-    <td><a name="SkImage_kRW_LegacyBitmapMode"> <code><strong>SkImage::kRW_LegacyBitmapMode </strong></code> </a></td><td>1</td><td></td>
-  </tr>
+
 </table>
 
-### Example
-
-<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
-
-### See Also
-
-incomplete
-
-
-
 <a name="SkImage_asLegacyBitmap"></a>
 ## asLegacyBitmap
 
 <pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
-bool asLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode legacyBitmapMode) const
+bool asLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const
 </pre>
 
 Creates raster <a href="SkBitmap_Reference#Bitmap">Bitmap</a> with same pixels as <a href="#Image">Image</a>. If <a href="#SkImage_asLegacyBitmap_legacyBitmapMode">legacyBitmapMode</a> is
@@ -2199,7 +2185,7 @@
 <table>  <tr>    <td><a name="SkImage_asLegacyBitmap_bitmap"> <code><strong>bitmap </strong></code> </a></td> <td>
 storage for legacy <a href="SkBitmap_Reference#Bitmap">Bitmap</a></td>
   </tr>  <tr>    <td><a name="SkImage_asLegacyBitmap_legacyBitmapMode"> <code><strong>legacyBitmapMode </strong></code> </a></td> <td>
-one of: <a href="#SkImage_kRO_LegacyBitmapMode">kRO LegacyBitmapMode</a>, <a href="#SkImage_kRW_LegacyBitmapMode">kRW LegacyBitmapMode</a></td>
+to be deprecated</td>
   </tr>
 </table>
 
@@ -2209,11 +2195,11 @@
 
 ### Example
 
-<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+<div><fiddle-embed name="eddfe9735342052ce2f8869ee5eb737a" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
-incomplete
+<a href="#SkImage_MakeRasterData">MakeRasterData</a> <a href="#SkImage_makeRasterImage">makeRasterImage</a> <a href="#SkImage_makeNonTextureImage">makeNonTextureImage</a>
 
 ---
 
diff --git a/site/user/api/SkPaint_Reference.md b/site/user/api/SkPaint_Reference.md
index b9df684..0e6828a 100644
--- a/site/user/api/SkPaint_Reference.md
+++ b/site/user/api/SkPaint_Reference.md
@@ -2134,7 +2134,7 @@
   <tr>
     <td><a name="SkPaint_kStroke_Style"> <code><strong>SkPaint::kStroke_Style </strong></code> </a></td><td>1</td><td>Set to stroke geometry.
 Applies to <a href="SkRect_Reference#Rect">Rect</a>, <a href="undocumented#Region">Region</a>, <a href="undocumented#Round_Rect">Round Rect</a>, <a href="#Arc">Arcs</a>, <a href="#Circle">Circles</a>, <a href="#Oval">Ovals</a>, <a href="SkPath_Reference#Path">Path</a>, and <a href="undocumented#Text">Text</a>.
-<a href="#Arc">Arcs</a>, <a href="#Line">Lines</a>, and <a href="#Point">Points</a>, are always drawn as if <a href="#SkPaint_kStroke_Style">kStroke Style</a> is set,
+<a href="#Arc">Arcs</a>, <a href="#Line">Lines</a>, and points, are always drawn as if <a href="#SkPaint_kStroke_Style">kStroke Style</a> is set,
 and ignore the set <a href="#SkPaint_Style">Style</a>.
 The stroke construction is unaffected by the <a href="#Fill_Type">Path Fill Type</a>.</td>
   </tr>
diff --git a/site/user/api/SkSurface_Reference.md b/site/user/api/SkSurface_Reference.md
index a3b675e..3cc14e9 100644
--- a/site/user/api/SkSurface_Reference.md
+++ b/site/user/api/SkSurface_Reference.md
@@ -61,6 +61,7 @@
 | <a href="#SkSurface_readPixels">readPixels</a> | copies <a href="SkRect_Reference#Rect">Rect</a> of pixels |
 | <a href="#SkSurface_wait">wait</a> | rause commands until signaled |
 | <a href="#SkSurface_width">width</a> | returns pixel column count |
+| <a href="#SkSurface_writePixels">writePixels</a> | copies <a href="SkRect_Reference#Rect">Rect</a> of pixels |
 
 ## <a name="Constructor"></a> Constructor
 
@@ -1396,6 +1397,9 @@
 |  | <a href="#SkSurface_readPixels">readPixels(const SkPixmap& dst, int srcX, int srcY)</a> |
 |  | <a href="#SkSurface_readPixels_2">readPixels(const SkImageInfo& dstInfo, void* dstPixels, size t dstRowBytes, int srcX, int srcY)</a> |
 |  | <a href="#SkSurface_readPixels_3">readPixels(const SkBitmap& dst, int srcX, int srcY)</a> |
+| <a href="#SkSurface_writePixels">writePixels</a> | copies <a href="SkRect_Reference#Rect">Rect</a> of pixels |
+|  | <a href="#SkSurface_writePixels">writePixels(const SkPixmap& src, int dstX, int dstY)</a> |
+|  | <a href="#SkSurface_writePixels_2">writePixels(const SkBitmap& src, int dstX, int dstY)</a> |
 
 <a name="SkSurface_draw"></a>
 ## draw
@@ -1463,7 +1467,7 @@
 
 ### See Also
 
-<a href="#SkSurface_readPixels">readPixels</a><sup><a href="#SkSurface_readPixels_2">[2]</a></sup><sup><a href="#SkSurface_readPixels_3">[3]</a></sup>
+<a href="#SkSurface_readPixels">readPixels</a><sup><a href="#SkSurface_readPixels_2">[2]</a></sup><sup><a href="#SkSurface_readPixels_3">[3]</a></sup> <a href="#SkSurface_writePixels">writePixels</a><sup><a href="#SkSurface_writePixels_2">[2]</a></sup>
 
 ---
 
@@ -1520,7 +1524,7 @@
 
 ### See Also
 
-<a href="#SkSurface_peekPixels">peekPixels</a>
+<a href="#SkSurface_peekPixels">peekPixels</a> <a href="#SkSurface_writePixels">writePixels</a><sup><a href="#SkSurface_writePixels_2">[2]</a></sup>
 
 ---
 
@@ -1582,7 +1586,7 @@
 
 ### See Also
 
-<a href="#SkSurface_peekPixels">peekPixels</a>
+<a href="#SkSurface_peekPixels">peekPixels</a> <a href="#SkSurface_writePixels">writePixels</a><sup><a href="#SkSurface_writePixels_2">[2]</a></sup>
 
 ---
 
@@ -1639,7 +1643,78 @@
 
 ### See Also
 
-<a href="#SkSurface_peekPixels">peekPixels</a>
+<a href="#SkSurface_peekPixels">peekPixels</a> <a href="#SkSurface_writePixels">writePixels</a><sup><a href="#SkSurface_writePixels_2">[2]</a></sup>
+
+---
+
+<a name="SkSurface_writePixels"></a>
+## writePixels
+
+<pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
+void writePixels(const SkPixmap& src, int dstX, int dstY)
+</pre>
+
+Copies <a href="SkRect_Reference#Rect">Rect</a> of pixels from the <a href="#SkSurface_writePixels_src">src</a> <a href="SkPixmap_Reference#Pixmap">Pixmap</a> to the <a href="#Surface">Surface</a>.
+
+Source <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (<a href="#SkSurface_writePixels_src">src</a>.<a href="#SkSurface_width">width</a>, <a href="#SkSurface_writePixels_src">src</a>.<a href="#SkSurface_height">height</a>).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkSurface_writePixels_dstX">dstX</a>, <a href="#SkSurface_writePixels_dstY">dstY</a>) and(<a href="#SkSurface_writePixels_dstX">dstX</a> + <a href="#Surface">Surface</a> <a href="#SkSurface_width">width</a>, <a href="#SkSurface_writePixels_dstY">dstY</a> + <a href="#Surface">Surface</a> <a href="#SkSurface_height">height</a>).
+
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to <a href="#Surface">Surface</a> colorType() and <a href="#Surface">Surface</a> alphaType() if required.
+
+### Parameters
+
+<table>  <tr>    <td><a name="SkSurface_writePixels_src"> <code><strong>src </strong></code> </a></td> <td>
+storage for pixels to copy to <a href="#Surface">Surface</a></td>
+  </tr>  <tr>    <td><a name="SkSurface_writePixels_dstX"> <code><strong>dstX </strong></code> </a></td> <td>
+x position relative to <a href="#Surface">Surface</a> to begin copy; may be negative</td>
+  </tr>  <tr>    <td><a name="SkSurface_writePixels_dstY"> <code><strong>dstY </strong></code> </a></td> <td>
+x position relative to <a href="#Surface">Surface</a> to begin copy; may be negative</td>
+  </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkSurface_readPixels">readPixels</a><sup><a href="#SkSurface_readPixels_2">[2]</a></sup><sup><a href="#SkSurface_readPixels_3">[3]</a></sup> <a href="#SkSurface_peekPixels">peekPixels</a>
+
+---
+
+<a name="SkSurface_writePixels_2"></a>
+
+<pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
+void writePixels(const SkBitmap& src, int dstX, int dstY)
+</pre>
+
+Copies <a href="SkRect_Reference#Rect">Rect</a> of pixels from the <a href="#SkSurface_writePixels_2_src">src</a> <a href="SkBitmap_Reference#Bitmap">Bitmap</a> to the <a href="#Surface">Surface</a>.
+
+Source <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (<a href="#SkSurface_writePixels_2_src">src</a>.<a href="#SkSurface_width">width</a>, <a href="#SkSurface_writePixels_2_src">src</a>.<a href="#SkSurface_height">height</a>).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkSurface_writePixels_2_dstX">dstX</a>, <a href="#SkSurface_writePixels_2_dstY">dstY</a>) and(<a href="#SkSurface_writePixels_2_dstX">dstX</a> + <a href="#Surface">Surface</a> <a href="#SkSurface_width">width</a>, <a href="#SkSurface_writePixels_2_dstY">dstY</a> + <a href="#Surface">Surface</a> <a href="#SkSurface_height">height</a>).
+
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to <a href="#Surface">Surface</a> colorType() and <a href="#Surface">Surface</a> alphaType() if required.
+
+### Parameters
+
+<table>  <tr>    <td><a name="SkSurface_writePixels_2_src"> <code><strong>src </strong></code> </a></td> <td>
+storage for pixels to copy to <a href="#Surface">Surface</a></td>
+  </tr>  <tr>    <td><a name="SkSurface_writePixels_2_dstX"> <code><strong>dstX </strong></code> </a></td> <td>
+x position relative to <a href="#Surface">Surface</a> to begin copy; may be negative</td>
+  </tr>  <tr>    <td><a name="SkSurface_writePixels_2_dstY"> <code><strong>dstY </strong></code> </a></td> <td>
+x position relative to <a href="#Surface">Surface</a> to begin copy; may be negative</td>
+  </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkSurface_readPixels">readPixels</a><sup><a href="#SkSurface_readPixels_2">[2]</a></sup><sup><a href="#SkSurface_readPixels_3">[3]</a></sup> <a href="#SkSurface_peekPixels">peekPixels</a>
 
 ---
 
diff --git a/site/user/api/catalog.htm b/site/user/api/catalog.htm
index 3e434fc..296b53b 100644
--- a/site/user/api/catalog.htm
+++ b/site/user/api/catalog.htm
@@ -373,7 +373,7 @@
     },
         "SkCanvas_SaveLayerRec_SaveLayerRec": {
     "code": "void draw(SkCanvas* canvas) {\n    SkCanvas::SaveLayerRec rec1;\n    rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;\n    SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);\n    SkDebugf(\"rec1 %c= rec2\\n\", rec1.fBounds == rec2.fBounds\n            && rec1.fPaint == rec2.fPaint\n            && rec1.fBackdrop == rec2.fBackdrop\n            && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');\n}",
-    "hash": "ac7c834dce2eac6ef49c15e820e94003",
+    "hash": "b5cea1eed80a0eb04ddbab3f36dff73f",
     "file": "SkCanvas_Reference",
     "name": "SkCanvas::SaveLayerRec::SaveLayerRec",
         "stdout": "rec1 == rec2\\n"
@@ -4950,19 +4950,11 @@
     "file": "SkImageInfo_Reference",
     "name": "SkImageInfo::width()"
 },
-    "SkImage_LegacyBitmapMode": {
-    "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
-    "width": 256,
-    "height": 256,
-    "hash": "882e8e0103048009a25cfc20400492f7",
-    "file": "SkImage_Reference",
-    "name": "SkImage::LegacyBitmapMode"
-},
     "SkImage_MakeBackendTextureFromSkImage": {
-    "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
+    "code": "static sk_sp<SkImage> create_gpu_image(GrContext* grContext) {\n    const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);\n    auto surface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));\n    SkCanvas* canvas = surface->getCanvas();\n    canvas->clear(SK_ColorWHITE);\n    SkPaint paint;\n    paint.setColor(SK_ColorBLACK);\n    canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);\n    return surface->makeImageSnapshot();\n}\n\nvoid draw(SkCanvas* canvas) {    \n    GrContext* grContext = canvas->getGrContext();\n    if (!grContext) {\n        return;\n    }\n    sk_sp<SkImage> backEndImage = create_gpu_image(grContext);\n    canvas->drawImage(backEndImage, 0, 0);\n    GrBackendTexture texture;\n    SkImage::BackendTextureReleaseProc proc;\n    if (!SkImage::MakeBackendTextureFromSkImage(grContext, std::move(backEndImage),\n            &texture, &proc)) {\n        return;\n    }\n    sk_sp<SkImage> i2 = SkImage::MakeFromTexture(grContext, texture, kTopLeft_GrSurfaceOrigin,\n            kN32_SkColorType, kOpaque_SkAlphaType, nullptr);\n    canvas->drawImage(i2, 30, 30);\n}\n",
     "width": 256,
-    "height": 256,
-    "hash": "882e8e0103048009a25cfc20400492f7",
+    "height": 64,
+    "hash": "98e70337c2964abd2624239d28bbecd7",
     "file": "SkImage_Reference",
     "name": "SkImage::MakeBackendTextureFromSkImage"
 },
@@ -5023,10 +5015,10 @@
     "name": "SkImage::MakeFromPicture"
 },
     "SkImage_MakeFromTexture_3": {
-    "code": "void draw(SkCanvas* canvas) {\n    GrContext* context = canvas->getGrContext();\n    if (!context) {\n       return;\n    }\n    canvas->scale(.25f, .25f);\n    int x = 0;\n    for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {\n        sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,\n               origin, kOpaque_SkAlphaType, nullptr);\n        canvas->drawImage(image, x, 0);\n    x += 512;\n    }\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    GrContext* context = canvas->getGrContext();\n    if (!context) {\n       return;\n    }\n    canvas->scale(.25f, .25f);\n    int x = 0;\n    for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {\n        sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,\n               origin, kN32_SkColorType, kOpaque_SkAlphaType, nullptr);\n        canvas->drawImage(image, x, 0);\n    x += 512;\n    }\n}",
     "width": 256,
     "height": 128,
-    "hash": "d5e43961a54548f445eece91d517381c",
+    "hash": "fdc498de45b53569743ec13012bf476c",
     "file": "SkImage_Reference",
     "name": "SkImage::MakeFromTexture_3"
 },
@@ -5063,10 +5055,10 @@
     "name": "SkImage::alphaType"
 },
     "SkImage_asLegacyBitmap": {
-    "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkBitmap bitImage;\n    if (image->asLegacyBitmap(&bitImage, SkImage::kRO_LegacyBitmapMode)) {\n        canvas->drawBitmap(bitImage, 0, 0);\n    }\n    GrContext* grContext = canvas->getGrContext();\n    if (!grContext) {\n        return;\n    }\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(grContext, backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kOpaque_SkAlphaType, nullptr));\n    canvas->drawImage(textureImage, 45, 45);\n    if (textureImage->asLegacyBitmap(&bitImage, SkImage::kRO_LegacyBitmapMode)) {\n        canvas->drawBitmap(bitImage, 90, 90);\n    }\n}",
     "width": 256,
     "height": 256,
-    "hash": "882e8e0103048009a25cfc20400492f7",
+    "hash": "eddfe9735342052ce2f8869ee5eb737a",
     "file": "SkImage_Reference",
     "name": "SkImage::asLegacyBitmap"
 },
@@ -7006,6 +6998,22 @@
     "file": "SkSurface_Reference",
     "name": "SkSurface::wait()"
 },
+    "SkSurface_writePixels": {
+    "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
+    "width": 256,
+    "height": 256,
+    "hash": "882e8e0103048009a25cfc20400492f7",
+    "file": "SkSurface_Reference",
+    "name": "SkSurface::writePixels"
+},
+    "SkSurface_writePixels_2": {
+    "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
+    "width": 256,
+    "height": 256,
+    "hash": "882e8e0103048009a25cfc20400492f7",
+    "file": "SkSurface_Reference",
+    "name": "SkSurface::writePixels_2"
+},
     "SkYUVColorSpace": {
     "code": "void draw(SkCanvas* canvas) {\n    // incomplete\n}",
     "width": 256,
@@ -7231,4 +7239,4 @@
 ></canvas >
 </body>
 </html>
-
+    
\ No newline at end of file
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index d1b6382..0264f50 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -1822,6 +1822,11 @@
         kExternal,
     };
 
+	enum class SkipFirstLine {
+		kNo,
+		kYes,
+	};
+
     enum class Wrote {
         kNone,
         kLF,
@@ -1859,7 +1864,9 @@
         return 0 == size;
     }
 
-    void descriptionOut(const Definition* def);
+	void constOut(const Definition* memberStart, const Definition& child,
+		const Definition* bmhConst);
+    void descriptionOut(const Definition* def, SkipFirstLine );
     void enumHeaderOut(const RootDefinition* root, const Definition& child);
     void enumMembersOut(const RootDefinition* root, Definition& child);
     void enumSizeItems(const Definition& child);
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index b4b0f0f..385b9c9 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -342,8 +342,10 @@
                         def = root->find(withParens, RootDefinition::AllowParens::kNo);
                     }
                     if (!def) {
-                        SkDebugf("method missing from bmh: %s\n", fullName.c_str());
-                        fFailed = true;
+                        if (!root->fDeprecated) {
+                            SkDebugf("method missing from bmh: %s\n", fullName.c_str());
+                            fFailed = true;
+                        }
                         break;
                     }
                     if (def->crossCheck2(token)) {
@@ -389,8 +391,10 @@
                             def = root->find(anonName, RootDefinition::AllowParens::kYes);
                         }
                         if (!def) {
-                            SkDebugf("enum missing from bmh: %s\n", fullName.c_str());
-                            fFailed = true;
+                            if (!root->fDeprecated) {
+                                SkDebugf("enum missing from bmh: %s\n", fullName.c_str());
+                                fFailed = true;
+                            }
                             break;
                         }
                     }
@@ -402,8 +406,10 @@
                         }
                     }
                     if (MarkType::kCode != def->fMarkType) {
-                        SkDebugf("enum code missing from bmh: %s\n", fullName.c_str());
-                        fFailed = true;
+                        if (!root->fDeprecated) {
+                            SkDebugf("enum code missing from bmh: %s\n", fullName.c_str());
+                            fFailed = true;
+                        }
                         break;
                     }
                     if (def->crossCheck(token)) {
@@ -423,8 +429,10 @@
                         }
                         if (!def) {
                             if (string::npos == child->fName.find("Legacy_")) {
-                                SkDebugf("const missing from bmh: %s\n", constName.c_str());
-                                fFailed = true;
+                                if (!root->fDeprecated) {
+                                    SkDebugf("const missing from bmh: %s\n", constName.c_str());
+                                    fFailed = true;
+                                }
                             }
                         } else {
                             def->fVisited = true;
@@ -434,7 +442,7 @@
                 case MarkType::kMember:
                     if (def) {
                         def->fVisited = true;
-                    } else {
+                    } else if (!root->fDeprecated) {
                         SkDebugf("member missing from bmh: %s\n", fullName.c_str());
                         fFailed = true;
                     }
@@ -442,7 +450,7 @@
                 case MarkType::kTypedef:
                     if (def) {
                         def->fVisited = true;
-                    } else {
+                    } else if (!root->fDeprecated) {
                         SkDebugf("typedef missing from bmh: %s\n", fullName.c_str());
                         fFailed = true;
                     }
@@ -475,7 +483,7 @@
     }
     if (crossChecks) {
         if (1 == crossChecks) {
-            SkDebugf("%s", firstCheck.c_str());
+            SkDebugf(" %s", firstCheck.c_str());
         }
         SkDebugf("\n");
     }
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 77baca0..dd5df8f 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -7,11 +7,34 @@
 
 #include "bookmaker.h"
 
-void IncludeWriter::descriptionOut(const Definition* def) {
+void IncludeWriter::constOut(const Definition* memberStart, const Definition& child,
+	const Definition* bmhConst) {
+	const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
+		memberStart->fContentStart;
+	this->writeBlockTrim((int) (bodyEnd - fStart), fStart);  // may write nothing
+	this->lf(2);
+	this->writeCommentHeader();
+	fIndent += 4;
+	this->descriptionOut(bmhConst, SkipFirstLine::kYes);
+	fIndent -= 4;
+	this->writeCommentTrailer();
+	fStart = memberStart->fContentStart;
+}
+
+void IncludeWriter::descriptionOut(const Definition* def, SkipFirstLine skipFirstLine) {
     const char* commentStart = def->fContentStart;
-    int commentLen = (int) (def->fContentEnd - commentStart);
-    bool breakOut = false;
+	if (SkipFirstLine::kYes == skipFirstLine) {
+		TextParser parser(def);
+		SkAssertResult(parser.skipLine());
+		commentStart = parser.fChar;
+	}
+	int commentLen = (int) (def->fContentEnd - commentStart);
+	bool breakOut = false;
     SkDEBUGCODE(bool wroteCode = false);
+	if (def->fDeprecated) {
+		this->writeString(def->fToBeDeprecated ? "To be deprecated soon." : "Deprecated.");
+		this->lfcr();
+	}
     for (auto prop : def->fChildren) {
         switch (prop->fMarkType) {
             case MarkType::kCode: {
@@ -52,14 +75,13 @@
             case MarkType::kDefinedBy:
                 commentStart = prop->fTerminator;
                 break;
+			case MarkType::kBug: {
+				string bugstr("(see skbug.com/" + string(prop->fContentStart,
+					prop->fContentEnd - prop->fContentStart) + ')');
+				this->writeString(bugstr);
+				this->lfcr();
+			}
             case MarkType::kDeprecated:
-                SkASSERT(def->fDeprecated);
-                if (def->fToBeDeprecated) {
-                    this->writeString("To be deprecated soon.");
-                } else {
-                    this->writeString("Deprecated.");
-                }
-                this->lfcr();
             case MarkType::kPrivate:
                 commentLen = (int) (prop->fStart - commentStart);
                 if (commentLen > 0) {
@@ -71,7 +93,9 @@
                 commentStart = prop->fContentStart;
                 if (def->fToBeDeprecated) {
                     commentStart += 4; // skip over "soon" // FIXME: this is awkward
-                }
+				} else if (MarkType::kBug == prop->fMarkType) {
+					commentStart = prop->fContentEnd;
+				}
                 commentLen = (int) (prop->fContentEnd - commentStart);
                 if (commentLen > 0) {
                     this->writeBlockIndent(commentLen, commentStart);
@@ -151,7 +175,7 @@
                         SkASSERT(MarkType::kColumn == column->fMarkType);
                         this->writeString("-");
                         this->writeSpace();
-                        this->descriptionOut(column);
+                        this->descriptionOut(column, SkipFirstLine::kNo);
                         this->lf(1);
                     }
                 }
@@ -396,9 +420,16 @@
             SkASSERT(currentEnumItem);
             if (currentEnumItem->fShort) {
                 this->indentToColumn(fEnumItemCommentTab);
-                this->writeString("//!<");
-                this->writeSpace();
-                this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
+				if (commentLen || currentEnumItem->fDeprecated) {
+					this->writeString("//!<");
+					this->writeSpace();
+					if (currentEnumItem->fDeprecated) {
+						this->writeString(child.fToBeDeprecated ? "to be deprecated soon"
+								: "deprecated");
+					} else {
+						this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
+					}
+				}
             }
             if (onePast) {
                 fIndent -= 4;
@@ -623,7 +654,7 @@
     }
     this->writeCommentHeader();
     fIndent += 4;
-    this->descriptionOut(method);
+    this->descriptionOut(method, SkipFirstLine::kNo);
     // compute indention column
     size_t column = 0;
     bool hasParmReturn = false;
@@ -687,7 +718,11 @@
     this->writeString(child.fName.c_str());
     fIndent += 4;
     this->lfcr();
-    this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
+	if (child.fDeprecated) {
+		this->writeString(child.fToBeDeprecated ? "to be deprecated soon" : "deprecated");
+	} else {
+		this->rewriteBlock((int)(commentEnd - commentStart), commentStart, Phrase::kNo);
+	}
     fIndent -= 4;
     this->lfcr();
     this->writeCommentTrailer();
@@ -929,6 +964,9 @@
 }
 
 bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefinition* root) {
+	if (!def->fTokens.size()) {
+		return true;
+	}
     ParentPair pair = { def, prevPair };
     // write bulk of original include up to class, method, enum, etc., excepting preceding comment
     // find associated bmh object
@@ -945,6 +983,8 @@
     bool inConstructor = false;
     bool inInline = false;
     bool eatOperator = false;
+	bool sawConst = false;
+	bool staticOnly = false;
     const Definition* requireDense = nullptr;
     const Definition* startDef = nullptr;
     for (auto& child : def->fTokens) {
@@ -1070,6 +1110,10 @@
                 methodName += string(fContinuation, continueEnd - fContinuation);
                 method = root->find(methodName, RootDefinition::AllowParens::kNo);
                 if (!method) {
+                    if (fBmhStructDef && fBmhStructDef->fDeprecated) {
+						fContinuation = nullptr;
+                        continue;
+                    }
                     fLineCount = child.fLineCount;
                     return this->reportError<bool>("method not found");
                 }
@@ -1095,6 +1139,9 @@
                 }
                 this->methodOut(method, child);
                 continue;
+            } else if (fBmhStructDef && fBmhStructDef->fDeprecated) {
+				fContinuation = nullptr;
+				continue;
             }
             fLineCount = child.fLineCount;
             return this->reportError<bool>("method not found");
@@ -1270,9 +1317,14 @@
                                 }
                             }
                             // FIXME: trigger error earlier if inner #Struct or #Class is missing #Code
-                            SkASSERT(nextBlock);  // FIXME: check enum for correct order earlier
-                            const char* commentStart = codeBlock->fTerminator;
-                            const char* commentEnd = nextBlock->fStart;
+                            const char* commentStart;
+                            const char* commentEnd;
+                            if (!fBmhStructDef->fDeprecated) {
+                                SkASSERT(codeBlock);
+                                SkASSERT(nextBlock);  // FIXME: check enum for correct order earlier
+                                commentStart = codeBlock->fTerminator;
+                                commentEnd = nextBlock->fStart;
+                            }
                             if (fIndentNext) {
 //                                fIndent += 4;
                             }
@@ -1291,7 +1343,18 @@
                 } break;
                 case KeyWord::kConst:
                 case KeyWord::kConstExpr:
+					sawConst = !memberStart || staticOnly;
+					if (!memberStart) {
+						memberStart = &child;
+						staticOnly = true;
+					}
+					break;
                 case KeyWord::kStatic:
+					if (!memberStart) {
+						memberStart = &child;
+						staticOnly = true;
+					}
+					break;
                 case KeyWord::kInt:
                 case KeyWord::kUint8_t:
                 case KeyWord::kUint16_t:
@@ -1301,7 +1364,9 @@
                 case KeyWord::kSize_t:
                 case KeyWord::kFloat:
                 case KeyWord::kBool:
+                case KeyWord::kChar:
                 case KeyWord::kVoid:
+					staticOnly = false;
                     if (!memberStart) {
                         memberStart = &child;
                     }
@@ -1412,6 +1477,7 @@
                     auto iter = def->fTokens.begin();
                     std::advance(iter, child.fParentIndex - 1);
                     memberStart = &*iter;
+					staticOnly = false;
                     if (!fStructMemberTab) {
                         SkASSERT(KeyWord::kStruct == def->fParent->fKeyWord);
                         fIndent += 4;
@@ -1421,13 +1487,38 @@
                         fIndentNext = true;
                     }
                 }
-                memberEnd = this->structMemberOut(memberStart, child);
-                startDef = &child;
-                fStart = child.fContentEnd + 1;
-                fDeferComment = nullptr;
-            }
+				SkASSERT(fBmhStructDef);
+				if (fBmhStructDef->fDeprecated) {
+					SkDebugf("");
+				} else {
+					memberEnd = this->structMemberOut(memberStart, child);
+					startDef = &child;
+					fStart = child.fContentEnd + 1;
+					fDeferComment = nullptr;
+				}
+            } else if (MarkType::kNone == child.fMarkType && sawConst
+					&& fEnumDef && !fEnumDef->fDeprecated) {
+				const Definition* bmhConst = nullptr;
+				string match;
+				if (root) {
+					match = root->fName + "::";
+				}
+				match += string(child.fContentStart, child.fContentEnd - child.fContentStart);
+				for (auto enumChild : fEnumDef->fChildren) {
+					if (MarkType::kConst == enumChild->fMarkType && enumChild->fName == match) {
+						bmhConst = enumChild;
+						break;
+					}
+				}
+				if (bmhConst) {
+					this->constOut(memberStart, child, bmhConst);
+					fDeferComment = nullptr;
+					sawConst = false;
+				}
+			}
             if (child.fMemberStart) {
                 memberStart = &child;
+				staticOnly = false;
             }
             const char attrDeprecated[] = "SK_ATTR_DEPRECATED";
             const size_t attrDeprecatedLen = sizeof(attrDeprecated) - 1;
@@ -1440,6 +1531,8 @@
         if (Definition::Type::kPunctuation == child.fType) {
             if (Punctuation::kSemicolon == child.fPunctuation) {
                 memberStart = nullptr;
+				sawConst = false;
+				staticOnly = false;
                 if (inStruct) {
                     fInStruct = false;
                 }