/**
* Reads a rectangle of pixels from a surface.
* @param surface the surface to read from.
+ * @param srcColorSpace color space of the surface
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
* @param width width of rectangle to read in pixels.
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
+ * @param dstColorSpace color space of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
* packed.
* @return true if the read succeeded, false if not. The read can fail because of an unsupported
* pixel configs
*/
- bool readSurfacePixels(GrSurface* surface,
+ bool readSurfacePixels(GrSurface* surface, SkColorSpace* srcColorSpace,
int left, int top, int width, int height,
- GrPixelConfig config, void* buffer,
+ GrPixelConfig config, SkColorSpace* dstColorSpace, void* buffer,
size_t rowBytes = 0,
uint32_t pixelOpsFlags = 0);
/**
* Writes a rectangle of pixels to a surface.
* @param surface the surface to write to.
+ * @param dstColorSpace color space of the surface
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
+ * @param srcColorSpace color space of the source buffer
* @param buffer memory to read pixels from
* @param rowBytes number of bytes between consecutive rows. Zero
* means rows are tightly packed.
* @return true if the write succeeded, false if not. The write can fail because of an
* unsupported combination of surface and src configs.
*/
- bool writeSurfacePixels(GrSurface* surface,
+ bool writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
int left, int top, int width, int height,
- GrPixelConfig config, const void* buffer,
+ GrPixelConfig config, SkColorSpace* srcColorSpace, const void* buffer,
size_t rowBytes,
uint32_t pixelOpsFlags = 0);
virtual const GrRenderTarget* asRenderTarget() const { return NULL; }
/**
- * Reads a rectangle of pixels from the surface.
+ * Reads a rectangle of pixels from the surface, possibly performing color space conversion.
+ * @param srcColorSpace color space of the source data (this surface)
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
* @param width width of rectangle to read in pixels.
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
+ * @param dstColorSpace color space of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
* packed.
* @return true if the read succeeded, false if not. The read can fail because of an unsupported
* pixel config.
*/
- bool readPixels(int left, int top, int width, int height,
+ bool readPixels(SkColorSpace* srcColorSpace,
+ int left, int top, int width, int height,
GrPixelConfig config,
+ SkColorSpace* dstColorSpace,
void* buffer,
size_t rowBytes = 0,
uint32_t pixelOpsFlags = 0);
/**
+ * Reads a rectangle of pixels from the surface. Does not perform any color space conversion.
+ * @param left left edge of the rectangle to read (inclusive)
+ * @param top top edge of the rectangle to read (inclusive)
+ * @param width width of rectangle to read in pixels.
+ * @param height height of rectangle to read in pixels.
+ * @param config the pixel config of the destination buffer
+ * @param buffer memory to read the rectangle into.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
+ *
+ * @return true if the read succeeded, false if not. The read can fail because of an unsupported
+ * pixel config.
+ */
+ bool readPixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) {
+ return this->readPixels(nullptr, left, top, width, height, config, nullptr, buffer,
+ rowBytes, pixelOpsFlags);
+ }
+
+ /**
* Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
- * rectangle.
+ * rectangle, possibly performing color space conversion.
+ * @param dstColorSpace color space of the destination (this surface)
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
+ * @param srcColorSpace color space of the source buffer
* @param buffer memory to read the rectangle from.
* @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
* packed.
* @return true if the write succeeded, false if not. The write can fail because of an
* unsupported pixel config.
*/
- bool writePixels(int left, int top, int width, int height,
+ bool writePixels(SkColorSpace* dstColorSpace,
+ int left, int top, int width, int height,
GrPixelConfig config,
+ SkColorSpace* srcColorSpace,
const void* buffer,
size_t rowBytes = 0,
uint32_t pixelOpsFlags = 0);
/**
+ * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
+ * rectangle. Does not perform any color space conversion.
+ * @param left left edge of the rectangle to write (inclusive)
+ * @param top top edge of the rectangle to write (inclusive)
+ * @param width width of rectangle to write in pixels.
+ * @param height height of rectangle to write in pixels.
+ * @param config the pixel config of the source buffer
+ * @param buffer memory to read the rectangle from.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
+ *
+ * @return true if the write succeeded, false if not. The write can fail because of an
+ * unsupported pixel config.
+ */
+ bool writePixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ const void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) {
+ return this->writePixels(nullptr, left, top, width, height, config, nullptr, buffer,
+ rowBytes, pixelOpsFlags);
+ }
+
+ /**
* After this returns any pending writes to the surface will be issued to the backend 3D API.
*/
void flushWrites();
}
const uint32_t pixelOpsFlags = 0;
- if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(),
+ if (!tex->readPixels(fInfo.colorSpace(), 0, 0, bitmap->width(), bitmap->height(),
SkImageInfo2GrPixelConfig(cacheInfo, *tex->getContext()->caps()),
- bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags)) {
+ cacheInfo.colorSpace(), bitmap->getPixels(), bitmap->rowBytes(),
+ pixelOpsFlags)) {
bitmap->reset();
return false;
}
return srcPI.convertPixelsTo(&dstPI, width, height);
}
-bool GrContext::writeSurfacePixels(GrSurface* surface,
+bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
int left, int top, int width, int height,
- GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
- uint32_t pixelOpsFlags) {
+ GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
+ const void* buffer, size_t rowBytes, uint32_t pixelOpsFlags) {
+ // TODO: Color space conversion
+
ASSERT_SINGLE_OWNER
RETURN_FALSE_IF_ABANDONED
ASSERT_OWNED_RESOURCE(surface);
return true;
}
-bool GrContext::readSurfacePixels(GrSurface* src,
+bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace,
int left, int top, int width, int height,
- GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
- uint32_t flags) {
+ GrPixelConfig dstConfig, SkColorSpace* dstColorSpace,
+ void* buffer, size_t rowBytes, uint32_t flags) {
+ // TODO: Color space conversion
+
ASSERT_SINGLE_OWNER
RETURN_FALSE_IF_ABANDONED
ASSERT_OWNED_RESOURCE(src);
return false;
}
- return rt->readPixels(x, y, dstInfo.width(), dstInfo.height(),
- config, dstBuffer, dstRowBytes, flags);
+ return rt->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
+ config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
}
bool GrRenderTargetContext::writePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
return false;
}
- return rt->writePixels(x, y, srcInfo.width(), srcInfo.height(),
- config, srcBuffer, srcRowBytes, flags);
+ return rt->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
+ config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
}
// Can 'path' be drawn as a pair of filled nested rectangles?
//////////////////////////////////////////////////////////////////////////////
-bool GrSurface::writePixels(int left, int top, int width, int height,
- GrPixelConfig config, const void* buffer, size_t rowBytes,
- uint32_t pixelOpsFlags) {
+bool GrSurface::writePixels(SkColorSpace* dstColorSpace, int left, int top, int width, int height,
+ GrPixelConfig config, SkColorSpace* srcColorSpace, const void* buffer,
+ size_t rowBytes, uint32_t pixelOpsFlags) {
// go through context so that all necessary flushing occurs
GrContext* context = this->getContext();
if (nullptr == context) {
return false;
}
- return context->writeSurfacePixels(this, left, top, width, height, config, buffer,
- rowBytes, pixelOpsFlags);
+ return context->writeSurfacePixels(this, dstColorSpace, left, top, width, height, config,
+ srcColorSpace, buffer, rowBytes, pixelOpsFlags);
}
-bool GrSurface::readPixels(int left, int top, int width, int height,
- GrPixelConfig config, void* buffer, size_t rowBytes,
- uint32_t pixelOpsFlags) {
+bool GrSurface::readPixels(SkColorSpace* srcColorSpace, int left, int top, int width, int height,
+ GrPixelConfig config, SkColorSpace* dstColorSpace, void* buffer,
+ size_t rowBytes, uint32_t pixelOpsFlags) {
// go through context so that all necessary flushing occurs
GrContext* context = this->getContext();
if (nullptr == context) {
return false;
}
- return context->readSurfacePixels(this, left, top, width, height, config, buffer,
- rowBytes, pixelOpsFlags);
+ return context->readSurfacePixels(this, srcColorSpace, left, top, width, height, config,
+ dstColorSpace, buffer, rowBytes, pixelOpsFlags);
}
void GrSurface::flushWrites() {
// let the GPU perform this transformation for us
flags = GrContext::kUnpremul_PixelOpsFlag;
}
- if (!fTexture->readPixels(srcX, srcY, info.width(), info.height(), config,
- pixels, rowBytes, flags)) {
+ if (!fTexture->readPixels(fColorSpace.get(), srcX, srcY, info.width(), info.height(), config,
+ info.colorSpace(), pixels, rowBytes, flags)) {
return false;
}
// do we have to manually fix-up the alpha channel?