Chromium Code Reviews| Index: src/gpu/GrAtlas.cpp |
| diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp |
| index 008bae2f00eaf3812bb7121d6f52941338cd86fb..6809a087e794923c2fde4bc80b38cf8eeda08be9 100644 |
| --- a/src/gpu/GrAtlas.cpp |
| +++ b/src/gpu/GrAtlas.cpp |
| @@ -29,6 +29,8 @@ GrPlot::GrPlot() : fDrawToken(NULL, 0) |
| } |
| GrPlot::~GrPlot() { |
| + SkDELETE_ARRAY(fPlotData); |
| + fPlotData = NULL; |
| delete fRects; |
| } |
| @@ -37,6 +39,9 @@ void GrPlot::init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, si |
| fAtlasMgr = mgr; |
| fOffset.set(offX * width, offY * height); |
| fBytesPerPixel = bpp; |
| + fPlotData = NULL; |
| + fDirtyRect.setEmpty(); |
| + fDirty = false; |
| } |
| static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) { |
| @@ -46,20 +51,45 @@ static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) |
| bool GrPlot::addSubImage(int width, int height, const void* image, |
| GrIPoint16* loc) { |
| + float percentFull = fRects->percentFull(); |
| if (!fRects->addRect(width, height, loc)) { |
| return false; |
| } |
| - SkAutoSMalloc<1024> storage; |
| - adjust_for_offset(loc, fOffset); |
| - GrContext* context = fTexture->getContext(); |
| - // We pass the flag that does not force a flush. We assume our caller is |
| - // smart and hasn't referenced the part of the texture we're about to update |
| - // since the last flush. |
| - context->writeTexturePixels(fTexture, |
| - loc->fX, loc->fY, width, height, |
| - fTexture->config(), image, 0, |
| - GrContext::kDontFlush_PixelOpsFlag); |
| + // create backing memory on first use |
|
robertphillips
2014/05/12 19:45:52
// Once the plot is nearly full we will revert to
jvanverth1
2014/05/12 20:44:04
Done.
|
| + int plotWidth = fRects->width(); |
| + int plotHeight = fRects->height(); |
| + if (NULL == fPlotData && 0.0f == percentFull) { |
| + fPlotData = SkNEW_ARRAY(unsigned char, fBytesPerPixel*plotWidth*plotHeight); |
| + memset(fPlotData, 0, fBytesPerPixel*plotWidth*plotHeight); |
| + } |
| + |
| + // if we have backing memory, copy to the memory and set for future upload |
| + if (NULL != fPlotData) { |
|
robertphillips
2014/05/12 19:45:52
const unsigned char* ?
jvanverth1
2014/05/12 20:44:04
Done.
|
| + unsigned char* imagePtr = (unsigned char*) image; |
| + // point ourselves at the right starting spot |
| + unsigned char* dataPtr = fPlotData; |
| + dataPtr += fBytesPerPixel*plotWidth*loc->fY; |
| + dataPtr += fBytesPerPixel*loc->fX; |
| + // copy into the data buffer |
| + for (int i = 0; i < height; ++i) { |
| + memcpy(dataPtr, imagePtr, fBytesPerPixel*width); |
| + dataPtr += fBytesPerPixel*plotWidth; |
| + imagePtr += fBytesPerPixel*width; |
| + } |
| + |
| + fDirtyRect.join(loc->fX, loc->fY, loc->fX + width, loc->fY + height); |
| + adjust_for_offset(loc, fOffset); |
| + fDirty = true; |
| + // otherwise, just upload the image directly |
| + } else { |
| + adjust_for_offset(loc, fOffset); |
| + GrContext* context = fTexture->getContext(); |
| + context->writeTexturePixels(fTexture, |
| + loc->fX, loc->fY, width, height, |
| + fTexture->config(), image, 0, |
| + GrContext::kDontFlush_PixelOpsFlag); |
| + } |
| #if FONT_CACHE_STATS |
| ++g_UploadCount; |
| @@ -68,6 +98,33 @@ bool GrPlot::addSubImage(int width, int height, const void* image, |
| return true; |
| } |
| +void GrPlot::uploadToTexture() { |
| + if (fDirty && NULL != fTexture) { |
| + GrContext* context = fTexture->getContext(); |
| + // We pass the flag that does not force a flush. We assume our caller is |
| + // smart and hasn't referenced the part of the texture we're about to update |
| + // since the last flush. |
| + int rowBytes = fBytesPerPixel*fRects->width(); |
|
robertphillips
2014/05/12 19:45:52
const unsigned char* ?
jvanverth1
2014/05/12 20:44:04
Done.
|
| + unsigned char* dataPtr = fPlotData; |
| + dataPtr += rowBytes*fDirtyRect.fTop; |
| + dataPtr += fBytesPerPixel*fDirtyRect.fLeft; |
| + context->writeTexturePixels(fTexture, |
| + fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop, |
| + fDirtyRect.width(), fDirtyRect.height(), |
| + fTexture->config(), dataPtr, |
| + rowBytes, |
| + GrContext::kDontFlush_PixelOpsFlag); |
| + fDirtyRect.setEmpty(); |
| + // If the Plot is nearly full, anything else we add will probably be small and one |
| + // at a time, so free up the memory and upload any new images directly. |
|
robertphillips
2014/05/12 19:45:52
static const int kNearlyFullTolerance = 0.85f; ?
jvanverth1
2014/05/12 20:44:04
Done.
|
| + if (fRects->percentFull() > 0.85f) { |
| + SkDELETE_ARRAY(fPlotData); |
| + fPlotData = NULL; |
| + } |
| + } |
|
robertphillips
2014/05/12 19:45:52
It seems like if we're going to clear fDirty out h
jvanverth1
2014/05/12 20:44:04
Cleaned up. We shouldn't hit the 'if' block unless
|
| + fDirty = false; |
| +} |
| + |
| void GrPlot::resetRects() { |
| SkASSERT(NULL != fRects); |
| fRects->reset(); |
| @@ -85,11 +142,14 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config, |
| fNumPlotsY = numPlotsY; |
| fTexture = NULL; |
| - int plotWidth = fBackingTextureSize.width() / fNumPlotsX; |
| - int plotHeight = fBackingTextureSize.height() / fNumPlotsY; |
| + int textureWidth = fBackingTextureSize.width(); |
| + int textureHeight = fBackingTextureSize.height(); |
| - SkASSERT(plotWidth * fNumPlotsX == fBackingTextureSize.width()); |
| - SkASSERT(plotHeight * fNumPlotsY == fBackingTextureSize.height()); |
| + int plotWidth = textureWidth / fNumPlotsX; |
| + int plotHeight = textureHeight / fNumPlotsY; |
| + |
| + SkASSERT(plotWidth * fNumPlotsX == textureWidth); |
| + SkASSERT(plotHeight * fNumPlotsY == textureHeight); |
| // set up allocated plots |
| size_t bpp = GrBytesPerPixel(fPixelConfig); |
| @@ -201,3 +261,13 @@ GrPlot* GrAtlasMgr::getUnusedPlot() { |
| return NULL; |
| } |
| + |
| +void GrAtlasMgr::uploadPlotsToTexture() { |
| + GrPlotList::Iter plotIter; |
| + plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); |
| + GrPlot* plot; |
| + while (NULL != (plot = plotIter.get())) { |
| + plot->uploadToTexture(); |
| + plotIter.next(); |
| + } |
| +} |