| /* | |
| * Copyright 2012 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "GrSurface.h" | |
| #include "GrSurfacePriv.h" | |
| #include "SkBitmap.h" | |
| #include "SkGr.h" | |
| #include "SkImageEncoder.h" | |
| #include <stdio.h> | |
| bool GrSurface::writePixels(int left, int top, int width, int height, | |
| GrPixelConfig config, const void* buffer, size_t rowBytes, | |
| uint32_t pixelOpsFlags) { | |
| // go through context so that all necessary flushing occurs | |
| GrContext* context = this->getContext(); | |
| if (NULL == context) { | |
| return false; | |
| } | |
| return context->writeSurfacePixels(this, left, top, width, height, config, buffer, rowBytes, | |
| pixelOpsFlags); | |
| } | |
| bool GrSurface::readPixels(int left, int top, int width, int height, | |
| GrPixelConfig config, void* buffer, size_t rowBytes, | |
| uint32_t pixelOpsFlags) { | |
| // go through context so that all necessary flushing occurs | |
| GrContext* context = this->getContext(); | |
| if (NULL == context) { | |
| return false; | |
| } | |
| GrRenderTarget* target = this->asRenderTarget(); | |
| if (target) { | |
| return context->readRenderTargetPixels(target, left, top, width, height, config, buffer, | |
| rowBytes, pixelOpsFlags); | |
| } | |
| return false; | |
| } | |
| SkImageInfo GrSurface::info() const { | |
| SkColorType colorType; | |
| SkColorProfileType profileType; | |
| if (!GrPixelConfig2ColorAndProfileType(this->config(), &colorType, &profileType)) { | |
| sk_throw(); | |
| } | |
| return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType, | |
| profileType); | |
| } | |
| // TODO: This should probably be a non-member helper function. It might only be needed in | |
| // debug or developer builds. | |
| bool GrSurface::savePixels(const char* filename) { | |
| SkBitmap bm; | |
| if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(this->width(), this->height()))) { | |
| return false; | |
| } | |
| bool result = this->readPixels(0, 0, this->width(), this->height(), kSkia8888_GrPixelConfig, | |
| bm.getPixels()); | |
| if (!result) { | |
| SkDebugf("------ failed to read pixels for %s\n", filename); | |
| return false; | |
| } | |
| // remove any previous version of this file | |
| remove(filename); | |
| if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) { | |
| SkDebugf("------ failed to encode %s\n", filename); | |
| remove(filename); // remove any partial file | |
| return false; | |
| } | |
| return true; | |
| } | |
| void GrSurface::flushWrites() { | |
| if (!this->wasDestroyed()) { | |
| this->getContext()->flushSurfaceWrites(this); | |
| } | |
| } | |
| void GrSurface::prepareForExternalRead() { | |
| if (!this->wasDestroyed()) { | |
| this->getContext()->prepareSurfaceForExternalRead(this); | |
| } | |
| } | |
| bool GrSurface::hasPendingRead() const { | |
| const GrTexture* thisTex = this->asTexture(); | |
| if (thisTex && thisTex->internalHasPendingRead()) { | |
| return true; | |
| } | |
| const GrRenderTarget* thisRT = this->asRenderTarget(); | |
| if (thisRT && thisRT->internalHasPendingRead()) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool GrSurface::hasPendingWrite() const { | |
| const GrTexture* thisTex = this->asTexture(); | |
| if (thisTex && thisTex->internalHasPendingWrite()) { | |
| return true; | |
| } | |
| const GrRenderTarget* thisRT = this->asRenderTarget(); | |
| if (thisRT && thisRT->internalHasPendingWrite()) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool GrSurface::hasPendingIO() const { | |
| const GrTexture* thisTex = this->asTexture(); | |
| if (thisTex && thisTex->internalHasPendingIO()) { | |
| return true; | |
| } | |
| const GrRenderTarget* thisRT = this->asRenderTarget(); | |
| if (thisRT && thisRT->internalHasPendingIO()) { | |
| return true; | |
| } | |
| return false; | |
| } |