LCOV - code coverage report
Current view: top level - gfx/gl - GLUploadHelpers.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 222 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "GLUploadHelpers.h"
       7             : 
       8             : #include "GLContext.h"
       9             : #include "mozilla/gfx/2D.h"
      10             : #include "gfxUtils.h"
      11             : #include "mozilla/gfx/Tools.h"  // For BytesPerPixel
      12             : #include "nsRegion.h"
      13             : #include "GfxTexturesReporter.h"
      14             : #include "mozilla/gfx/Logging.h"
      15             : 
      16             : namespace mozilla {
      17             : 
      18             : using namespace gfx;
      19             : 
      20             : namespace gl {
      21             : 
      22             : static unsigned int
      23           0 : DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat)
      24             : {
      25           0 :   unsigned int data = aPoint.y * aStride;
      26           0 :   data += aPoint.x * BytesPerPixel(aFormat);
      27           0 :   return data;
      28             : }
      29             : 
      30           0 : static GLint GetAddressAlignment(ptrdiff_t aAddress)
      31             : {
      32           0 :     if (!(aAddress & 0x7)) {
      33           0 :        return 8;
      34           0 :     } else if (!(aAddress & 0x3)) {
      35           0 :         return 4;
      36           0 :     } else if (!(aAddress & 0x1)) {
      37           0 :         return 2;
      38             :     } else {
      39           0 :         return 1;
      40             :     }
      41             : }
      42             : 
      43             : // Take texture data in a given buffer and copy it into a larger buffer,
      44             : // padding out the edge pixels for filtering if necessary
      45             : static void
      46           0 : CopyAndPadTextureData(const GLvoid* srcBuffer,
      47             :                       GLvoid* dstBuffer,
      48             :                       GLsizei srcWidth, GLsizei srcHeight,
      49             :                       GLsizei dstWidth, GLsizei dstHeight,
      50             :                       GLsizei stride, GLint pixelsize)
      51             : {
      52           0 :     unsigned char* rowDest = static_cast<unsigned char*>(dstBuffer);
      53           0 :     const unsigned char* source = static_cast<const unsigned char*>(srcBuffer);
      54             : 
      55           0 :     for (GLsizei h = 0; h < srcHeight; ++h) {
      56           0 :         memcpy(rowDest, source, srcWidth * pixelsize);
      57           0 :         rowDest += dstWidth * pixelsize;
      58           0 :         source += stride;
      59             :     }
      60             : 
      61           0 :     GLsizei padHeight = srcHeight;
      62             : 
      63             :     // Pad out an extra row of pixels so that edge filtering doesn't use garbage data
      64           0 :     if (dstHeight > srcHeight) {
      65           0 :         memcpy(rowDest, source - stride, srcWidth * pixelsize);
      66           0 :         padHeight++;
      67             :     }
      68             : 
      69             :     // Pad out an extra column of pixels
      70           0 :     if (dstWidth > srcWidth) {
      71           0 :         rowDest = static_cast<unsigned char*>(dstBuffer) + srcWidth * pixelsize;
      72           0 :         for (GLsizei h = 0; h < padHeight; ++h) {
      73           0 :             memcpy(rowDest, rowDest - pixelsize, pixelsize);
      74           0 :             rowDest += dstWidth * pixelsize;
      75             :         }
      76             :     }
      77           0 : }
      78             : 
      79             : // In both of these cases (for the Adreno at least) it is impossible
      80             : // to determine good or bad driver versions for POT texture uploads,
      81             : // so blacklist them all. Newer drivers use a different rendering
      82             : // string in the form "Adreno (TM) 200" and the drivers we've seen so
      83             : // far work fine with NPOT textures, so don't blacklist those until we
      84             : // have evidence of any problems with them.
      85             : bool
      86           0 : CanUploadSubTextures(GLContext* gl)
      87             : {
      88           0 :     if (!gl->WorkAroundDriverBugs())
      89           0 :         return true;
      90             : 
      91             :     // There are certain GPUs that we don't want to use glTexSubImage2D on
      92             :     // because that function can be very slow and/or buggy
      93           0 :     if (gl->Renderer() == GLRenderer::Adreno200 ||
      94           0 :         gl->Renderer() == GLRenderer::Adreno205)
      95             :     {
      96           0 :         return false;
      97             :     }
      98             : 
      99             :     // On PowerVR glTexSubImage does a readback, so it will be slower
     100             :     // than just doing a glTexImage2D() directly. i.e. 26ms vs 10ms
     101           0 :     if (gl->Renderer() == GLRenderer::SGX540 ||
     102           0 :         gl->Renderer() == GLRenderer::SGX530)
     103             :     {
     104           0 :         return false;
     105             :     }
     106             : 
     107           0 :     return true;
     108             : }
     109             : 
     110             : static void
     111           0 : TexSubImage2DWithUnpackSubimageGLES(GLContext* gl,
     112             :                                     GLenum target, GLint level,
     113             :                                     GLint xoffset, GLint yoffset,
     114             :                                     GLsizei width, GLsizei height,
     115             :                                     GLsizei stride, GLint pixelsize,
     116             :                                     GLenum format, GLenum type,
     117             :                                     const GLvoid* pixels)
     118             : {
     119           0 :     gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     120           0 :                      std::min(GetAddressAlignment((ptrdiff_t)pixels),
     121           0 :                               GetAddressAlignment((ptrdiff_t)stride)));
     122             :     // When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra
     123             :     // driver crash where the driver apparently tries to read
     124             :     // (stride - width * pixelsize) bytes past the end of the last input
     125             :     // row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH,
     126             :     // and then we upload the final row separately. See bug 697990.
     127           0 :     int rowLength = stride/pixelsize;
     128           0 :     gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
     129           0 :     gl->fTexSubImage2D(target,
     130             :                        level,
     131             :                        xoffset,
     132             :                        yoffset,
     133             :                        width,
     134             :                        height-1,
     135             :                        format,
     136             :                        type,
     137           0 :                        pixels);
     138           0 :     gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
     139           0 :     gl->fTexSubImage2D(target,
     140             :                        level,
     141             :                        xoffset,
     142           0 :                        yoffset+height-1,
     143             :                        width,
     144             :                        1,
     145             :                        format,
     146             :                        type,
     147           0 :                        (const unsigned char*)pixels+(height-1)*stride);
     148           0 :     gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     149           0 : }
     150             : 
     151             : static void
     152           0 : TexSubImage2DWithoutUnpackSubimage(GLContext* gl,
     153             :                                    GLenum target, GLint level,
     154             :                                    GLint xoffset, GLint yoffset,
     155             :                                    GLsizei width, GLsizei height,
     156             :                                    GLsizei stride, GLint pixelsize,
     157             :                                    GLenum format, GLenum type,
     158             :                                    const GLvoid* pixels)
     159             : {
     160             :     // Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
     161             :     // isn't supported. We make a copy of the texture data we're using,
     162             :     // such that we're using the whole row of data in the copy. This turns
     163             :     // out to be more efficient than uploading row-by-row; see bug 698197.
     164           0 :     unsigned char* newPixels = new (fallible) unsigned char[width*height*pixelsize];
     165             : 
     166           0 :     if (newPixels) {
     167           0 :         unsigned char* rowDest = newPixels;
     168           0 :         const unsigned char* rowSource = (const unsigned char*)pixels;
     169           0 :         for (int h = 0; h < height; h++) {
     170           0 :             memcpy(rowDest, rowSource, width*pixelsize);
     171           0 :             rowDest += width*pixelsize;
     172           0 :             rowSource += stride;
     173             :         }
     174             : 
     175           0 :         stride = width*pixelsize;
     176           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     177           0 :                          std::min(GetAddressAlignment((ptrdiff_t)newPixels),
     178           0 :                                   GetAddressAlignment((ptrdiff_t)stride)));
     179             :         gl->fTexSubImage2D(target,
     180             :                            level,
     181             :                            xoffset,
     182             :                            yoffset,
     183             :                            width,
     184             :                            height,
     185             :                            format,
     186             :                            type,
     187           0 :                            newPixels);
     188           0 :         delete [] newPixels;
     189           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     190             : 
     191             :     } else {
     192             :         // If we did not have sufficient memory for the required
     193             :         // temporary buffer, then fall back to uploading row-by-row.
     194           0 :         const unsigned char* rowSource = (const unsigned char*)pixels;
     195             : 
     196           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     197           0 :                          std::min(GetAddressAlignment((ptrdiff_t)pixels),
     198           0 :                                   GetAddressAlignment((ptrdiff_t)stride)));
     199             : 
     200           0 :         for (int i = 0; i < height; i++) {
     201           0 :             gl->fTexSubImage2D(target, level,
     202             :                                xoffset, yoffset + i,
     203             :                                width, 1,
     204           0 :                                format, type, rowSource);
     205           0 :             rowSource += stride;
     206             :         }
     207             : 
     208           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     209             :     }
     210           0 : }
     211             : 
     212             : static void
     213           0 : TexSubImage2DHelper(GLContext* gl,
     214             :                     GLenum target, GLint level,
     215             :                     GLint xoffset, GLint yoffset,
     216             :                     GLsizei width, GLsizei height, GLsizei stride,
     217             :                     GLint pixelsize, GLenum format,
     218             :                     GLenum type, const GLvoid* pixels)
     219             : {
     220           0 :     if (gl->IsGLES()) {
     221           0 :         if (stride == width * pixelsize) {
     222           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     223           0 :                              std::min(GetAddressAlignment((ptrdiff_t)pixels),
     224           0 :                                       GetAddressAlignment((ptrdiff_t)stride)));
     225             :             gl->fTexSubImage2D(target,
     226             :                                level,
     227             :                                xoffset,
     228             :                                yoffset,
     229             :                                width,
     230             :                                height,
     231             :                                format,
     232             :                                type,
     233           0 :                                pixels);
     234           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     235           0 :         } else if (gl->IsExtensionSupported(GLContext::EXT_unpack_subimage)) {
     236             :             TexSubImage2DWithUnpackSubimageGLES(gl, target, level, xoffset, yoffset,
     237             :                                                 width, height, stride,
     238           0 :                                                 pixelsize, format, type, pixels);
     239             : 
     240             :         } else {
     241             :             TexSubImage2DWithoutUnpackSubimage(gl, target, level, xoffset, yoffset,
     242             :                                               width, height, stride,
     243           0 :                                               pixelsize, format, type, pixels);
     244             :         }
     245             :     } else {
     246             :         // desktop GL (non-ES) path
     247           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     248           0 :                          std::min(GetAddressAlignment((ptrdiff_t)pixels),
     249           0 :                                   GetAddressAlignment((ptrdiff_t)stride)));
     250           0 :         int rowLength = stride/pixelsize;
     251           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
     252             :         gl->fTexSubImage2D(target,
     253             :                            level,
     254             :                            xoffset,
     255             :                            yoffset,
     256             :                            width,
     257             :                            height,
     258             :                            format,
     259             :                            type,
     260           0 :                            pixels);
     261           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
     262           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     263             :     }
     264           0 : }
     265             : 
     266             : static void
     267           0 : TexImage2DHelper(GLContext* gl,
     268             :                  GLenum target, GLint level, GLint internalformat,
     269             :                  GLsizei width, GLsizei height, GLsizei stride,
     270             :                  GLint pixelsize, GLint border, GLenum format,
     271             :                  GLenum type, const GLvoid* pixels)
     272             : {
     273           0 :     if (gl->IsGLES()) {
     274             : 
     275           0 :         NS_ASSERTION(format == (GLenum)internalformat,
     276             :                     "format and internalformat not the same for glTexImage2D on GLES2");
     277             : 
     278           0 :         MOZ_ASSERT(width >= 0 && height >= 0);
     279           0 :         if (!CanUploadNonPowerOfTwo(gl)
     280           0 :             && (stride != width * pixelsize
     281           0 :             || !IsPowerOfTwo((uint32_t)width)
     282           0 :             || !IsPowerOfTwo((uint32_t)height))) {
     283             : 
     284             :             // Pad out texture width and height to the next power of two
     285             :             // as we don't support/want non power of two texture uploads
     286           0 :             GLsizei paddedWidth = RoundUpPow2((uint32_t)width);
     287           0 :             GLsizei paddedHeight = RoundUpPow2((uint32_t)height);
     288             : 
     289           0 :             GLvoid* paddedPixels = new unsigned char[paddedWidth * paddedHeight * pixelsize];
     290             : 
     291             :             // Pad out texture data to be in a POT sized buffer for uploading to
     292             :             // a POT sized texture
     293             :             CopyAndPadTextureData(pixels, paddedPixels, width, height,
     294           0 :                                   paddedWidth, paddedHeight, stride, pixelsize);
     295             : 
     296           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     297           0 :                              std::min(GetAddressAlignment((ptrdiff_t)paddedPixels),
     298           0 :                                       GetAddressAlignment((ptrdiff_t)paddedWidth * pixelsize)));
     299             :             gl->fTexImage2D(target,
     300             :                             border,
     301             :                             internalformat,
     302             :                             paddedWidth,
     303             :                             paddedHeight,
     304             :                             border,
     305             :                             format,
     306             :                             type,
     307           0 :                             paddedPixels);
     308           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     309             : 
     310           0 :             delete[] static_cast<unsigned char*>(paddedPixels);
     311           0 :             return;
     312             :         }
     313             : 
     314           0 :         if (stride == width * pixelsize) {
     315           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     316           0 :                              std::min(GetAddressAlignment((ptrdiff_t)pixels),
     317           0 :                                       GetAddressAlignment((ptrdiff_t)stride)));
     318             :             gl->fTexImage2D(target,
     319             :                             border,
     320             :                             internalformat,
     321             :                             width,
     322             :                             height,
     323             :                             border,
     324             :                             format,
     325             :                             type,
     326           0 :                             pixels);
     327           0 :             gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     328             :         } else {
     329             :             // Use GLES-specific workarounds for GL_UNPACK_ROW_LENGTH; these are
     330             :             // implemented in TexSubImage2D.
     331             :             gl->fTexImage2D(target,
     332             :                             border,
     333             :                             internalformat,
     334             :                             width,
     335             :                             height,
     336             :                             border,
     337             :                             format,
     338             :                             type,
     339           0 :                             nullptr);
     340             :             TexSubImage2DHelper(gl,
     341             :                                 target,
     342             :                                 level,
     343             :                                 0,
     344             :                                 0,
     345             :                                 width,
     346             :                                 height,
     347             :                                 stride,
     348             :                                 pixelsize,
     349             :                                 format,
     350             :                                 type,
     351           0 :                                 pixels);
     352             :         }
     353             :     } else {
     354             :         // desktop GL (non-ES) path
     355             : 
     356           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
     357           0 :                          std::min(GetAddressAlignment((ptrdiff_t)pixels),
     358           0 :                                   GetAddressAlignment((ptrdiff_t)stride)));
     359           0 :         int rowLength = stride/pixelsize;
     360           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
     361             :         gl->fTexImage2D(target,
     362             :                         level,
     363             :                         internalformat,
     364             :                         width,
     365             :                         height,
     366             :                         border,
     367             :                         format,
     368             :                         type,
     369           0 :                         pixels);
     370           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
     371           0 :         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     372             :     }
     373             : }
     374             : 
     375             : SurfaceFormat
     376           0 : UploadImageDataToTexture(GLContext* gl,
     377             :                          unsigned char* aData,
     378             :                          int32_t aStride,
     379             :                          SurfaceFormat aFormat,
     380             :                          const nsIntRegion& aDstRegion,
     381             :                          GLuint aTexture,
     382             :                          const gfx::IntSize& aSize,
     383             :                          size_t* aOutUploadSize,
     384             :                          bool aNeedInit,
     385             :                          GLenum aTextureUnit,
     386             :                          GLenum aTextureTarget)
     387             : {
     388           0 :     gl->MakeCurrent();
     389           0 :     gl->fActiveTexture(aTextureUnit);
     390           0 :     gl->fBindTexture(aTextureTarget, aTexture);
     391             : 
     392           0 :     GLenum format = 0;
     393           0 :     GLenum internalFormat = 0;
     394           0 :     GLenum type = 0;
     395           0 :     int32_t pixelSize = BytesPerPixel(aFormat);
     396           0 :     SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN;
     397             : 
     398           0 :     MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
     399             :                gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);
     400             : 
     401           0 :     switch (aFormat) {
     402             :         case SurfaceFormat::B8G8R8A8:
     403           0 :             if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
     404           0 :               format = LOCAL_GL_BGRA;
     405           0 :               surfaceFormat = SurfaceFormat::R8G8B8A8;
     406           0 :               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
     407             :             } else {
     408           0 :               format = LOCAL_GL_RGBA;
     409           0 :               surfaceFormat = SurfaceFormat::B8G8R8A8;
     410           0 :               type = LOCAL_GL_UNSIGNED_BYTE;
     411             :             }
     412           0 :             internalFormat = LOCAL_GL_RGBA;
     413           0 :             break;
     414             :         case SurfaceFormat::B8G8R8X8:
     415             :             // Treat BGRX surfaces as BGRA except for the surface
     416             :             // format used.
     417           0 :             if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
     418           0 :               format = LOCAL_GL_BGRA;
     419           0 :               surfaceFormat = SurfaceFormat::R8G8B8X8;
     420           0 :               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
     421             :             } else {
     422           0 :               format = LOCAL_GL_RGBA;
     423           0 :               surfaceFormat = SurfaceFormat::B8G8R8X8;
     424           0 :               type = LOCAL_GL_UNSIGNED_BYTE;
     425             :             }
     426           0 :             internalFormat = LOCAL_GL_RGBA;
     427           0 :             break;
     428             :         case SurfaceFormat::R8G8B8A8:
     429           0 :             if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
     430             :               // Upload our RGBA as BGRA, but store that the uploaded format is
     431             :               // BGRA. (sample from R to get B)
     432           0 :               format = LOCAL_GL_BGRA;
     433           0 :               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
     434           0 :               surfaceFormat = SurfaceFormat::B8G8R8A8;
     435             :             } else {
     436           0 :               format = LOCAL_GL_RGBA;
     437           0 :               type = LOCAL_GL_UNSIGNED_BYTE;
     438           0 :               surfaceFormat = SurfaceFormat::R8G8B8A8;
     439             :             }
     440           0 :             internalFormat = LOCAL_GL_RGBA;
     441           0 :             break;
     442             :         case SurfaceFormat::R8G8B8X8:
     443             :             // Treat RGBX surfaces as RGBA except for the surface
     444             :             // format used.
     445           0 :             if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
     446           0 :               format = LOCAL_GL_BGRA;
     447           0 :               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
     448           0 :               surfaceFormat = SurfaceFormat::B8G8R8X8;
     449             :             } else {
     450           0 :               format = LOCAL_GL_RGBA;
     451           0 :               type = LOCAL_GL_UNSIGNED_BYTE;
     452           0 :               surfaceFormat = SurfaceFormat::R8G8B8X8;
     453             :             }
     454           0 :             internalFormat = LOCAL_GL_RGBA;
     455           0 :             break;
     456             :         case SurfaceFormat::R5G6B5_UINT16:
     457           0 :             internalFormat = format = LOCAL_GL_RGB;
     458           0 :             type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
     459           0 :             surfaceFormat = SurfaceFormat::R5G6B5_UINT16;
     460           0 :             break;
     461             :         case SurfaceFormat::A8:
     462           0 :             internalFormat = format = LOCAL_GL_LUMINANCE;
     463           0 :             type = LOCAL_GL_UNSIGNED_BYTE;
     464             :             // We don't have a specific luminance shader
     465           0 :             surfaceFormat = SurfaceFormat::A8;
     466           0 :             break;
     467             :         default:
     468           0 :             NS_ASSERTION(false, "Unhandled image surface format!");
     469             :     }
     470             : 
     471           0 :     if (aOutUploadSize) {
     472           0 :         *aOutUploadSize = 0;
     473             :     }
     474             : 
     475           0 :     if (aNeedInit || !CanUploadSubTextures(gl)) {
     476             :         // If the texture needs initialized, or we are unable to
     477             :         // upload sub textures, then initialize and upload the entire
     478             :         // texture.
     479           0 :         TexImage2DHelper(gl,
     480             :                          aTextureTarget,
     481             :                          0,
     482             :                          internalFormat,
     483           0 :                          aSize.width,
     484           0 :                          aSize.height,
     485             :                          aStride,
     486             :                          pixelSize,
     487             :                          0,
     488             :                          format,
     489             :                          type,
     490           0 :                          aData);
     491             : 
     492           0 :         if (aOutUploadSize && aNeedInit) {
     493           0 :             uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
     494           0 :             size_t numTexels = size_t(aSize.width) * size_t(aSize.height);
     495           0 :             *aOutUploadSize += texelSize * numTexels;
     496             :         }
     497             :     } else {
     498             :         // Upload each rect in the region to the texture
     499           0 :         for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) {
     500           0 :             const IntRect& rect = iter.Get();
     501             :             const unsigned char* rectData =
     502           0 :                 aData + DataOffset(rect.TopLeft(), aStride, aFormat);
     503             : 
     504             :             TexSubImage2DHelper(gl,
     505             :                                 aTextureTarget,
     506             :                                 0,
     507           0 :                                 rect.x,
     508           0 :                                 rect.y,
     509           0 :                                 rect.width,
     510           0 :                                 rect.height,
     511             :                                 aStride,
     512             :                                 pixelSize,
     513             :                                 format,
     514             :                                 type,
     515           0 :                                 rectData);
     516             :         }
     517             :     }
     518             : 
     519           0 :     return surfaceFormat;
     520             : }
     521             : 
     522             : SurfaceFormat
     523           0 : UploadSurfaceToTexture(GLContext* gl,
     524             :                        DataSourceSurface* aSurface,
     525             :                        const nsIntRegion& aDstRegion,
     526             :                        GLuint aTexture,
     527             :                        const gfx::IntSize& aSize,
     528             :                        size_t* aOutUploadSize,
     529             :                        bool aNeedInit,
     530             :                        const gfx::IntPoint& aSrcPoint,
     531             :                        GLenum aTextureUnit,
     532             :                        GLenum aTextureTarget)
     533             : {
     534             : 
     535           0 :     int32_t stride = aSurface->Stride();
     536           0 :     SurfaceFormat format = aSurface->GetFormat();
     537           0 :     unsigned char* data = aSurface->GetData() +
     538           0 :         DataOffset(aSrcPoint, stride, format);
     539             : 
     540           0 :     return UploadImageDataToTexture(gl, data, stride, format,
     541             :                                     aDstRegion, aTexture, aSize,
     542             :                                     aOutUploadSize, aNeedInit,
     543           0 :                                     aTextureUnit, aTextureTarget);
     544             : }
     545             : 
     546             : bool
     547           0 : CanUploadNonPowerOfTwo(GLContext* gl)
     548             : {
     549           0 :     if (!gl->WorkAroundDriverBugs())
     550           0 :         return true;
     551             : 
     552             :     // Some GPUs driver crash when uploading non power of two 565 textures.
     553           0 :     return gl->Renderer() != GLRenderer::Adreno200 &&
     554           0 :            gl->Renderer() != GLRenderer::Adreno205;
     555             : }
     556             : 
     557             : } // namespace gl
     558             : } // namespace mozilla

Generated by: LCOV version 1.13