nsRegion
nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const
{
  nsRegion result;
  for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
    // FilterSpaceToFrameSpace rounds out, so this works.
    result.Or(result, FilterSpaceToFrameSpace(iter.Get()));
  }
  return result;
}
void
AppendToString(std::stringstream& aStream, const nsIntRegion& r,
               const char* pfx, const char* sfx)
{
  aStream << pfx;

  aStream << "< ";
  for (auto iter = r.RectIter(); !iter.Done(); iter.Next()) {
    AppendToString(aStream, iter.Get());
    aStream << "; ";
  }
  aStream << ">";

  aStream << sfx;
}
Example #3
0
/* static */ bool
HwcUtils::PrepareVisibleRegion(const nsIntRegion& aVisible,
                               const gfx::Matrix& aLayerTransform,
                               const gfx::Matrix& aLayerBufferTransform,
                               nsIntRect aClip, nsIntRect aBufferRect,
                               RectVector* aVisibleRegionScreen,
                               bool& aIsVisible) {
    const float MIN_SRC_WIDTH = 2.f;
    const float MIN_SRC_HEIGHT = 2.f;

    gfxMatrix layerTransform = gfx::ThebesMatrix(aLayerTransform);
    gfxMatrix layerBufferTransform = gfx::ThebesMatrix(aLayerBufferTransform);
    gfxRect bufferRect =
        layerBufferTransform.TransformBounds(ThebesRect(aBufferRect));
    gfxMatrix inverse = gfx::ThebesMatrix(aLayerBufferTransform);
    inverse.Invert();
    aIsVisible = false;

    for (auto iter = aVisible.RectIter(); !iter.Done(); iter.Next()) {
        gfxRect screenRect =
            layerTransform.TransformBounds(ThebesRect(iter.Get()));
        screenRect.IntersectRect(screenRect, bufferRect);
        screenRect.IntersectRect(screenRect, ThebesRect(aClip));
        screenRect.Round();
        if (screenRect.IsEmpty()) {
            continue;
        }

        hwc_rect_t visibleRectScreen;
        visibleRectScreen.left = screenRect.x;
        visibleRectScreen.top  = screenRect.y;
        visibleRectScreen.right  = screenRect.XMost();
        visibleRectScreen.bottom = screenRect.YMost();

        gfxRect srcCrop = inverse.TransformBounds(screenRect);
        // When src crop is very small, HWC could not render correctly in some cases.
        // See Bug 1169093
        if(srcCrop.Width() < MIN_SRC_WIDTH || srcCrop.Height() < MIN_SRC_HEIGHT) {
            return false;
        }

        aVisibleRegionScreen->push_back(visibleRectScreen);
        aIsVisible = true;
    }

    return true;
}
Example #4
0
void
Compositor::DrawDiagnostics(DiagnosticFlags aFlags,
                            const nsIntRegion& aVisibleRegion,
                            const gfx::IntRect& aClipRect,
                            const gfx::Matrix4x4& aTransform,
                            uint32_t aFlashCounter)
{
  if (!ShouldDrawDiagnostics(aFlags)) {
    return;
  }

  if (aVisibleRegion.GetNumRects() > 1) {
    for (auto iter = aVisibleRegion.RectIter(); !iter.Done(); iter.Next()) {
      DrawDiagnostics(aFlags | DiagnosticFlags::REGION_RECT,
                      IntRectToRect(iter.Get()), aClipRect, aTransform,
                      aFlashCounter);
    }
  }

  DrawDiagnostics(aFlags, IntRectToRect(aVisibleRegion.GetBounds()),
                  aClipRect, aTransform, aFlashCounter);
}
Example #5
0
SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
                         unsigned char* aData,
                         int32_t aStride,
                         SurfaceFormat aFormat,
                         const nsIntRegion& aDstRegion,
                         GLuint aTexture,
                         const gfx::IntSize& aSize,
                         size_t* aOutUploadSize,
                         bool aNeedInit,
                         GLenum aTextureUnit,
                         GLenum aTextureTarget)
{
    gl->MakeCurrent();
    gl->fActiveTexture(aTextureUnit);
    gl->fBindTexture(aTextureTarget, aTexture);

    GLenum format = 0;
    GLenum internalFormat = 0;
    GLenum type = 0;
    int32_t pixelSize = BytesPerPixel(aFormat);
    SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN;

    MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
               gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);

    switch (aFormat) {
        case SurfaceFormat::B8G8R8A8:
            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
              format = LOCAL_GL_BGRA;
              surfaceFormat = SurfaceFormat::R8G8B8A8;
              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
            } else {
              format = LOCAL_GL_RGBA;
              surfaceFormat = SurfaceFormat::B8G8R8A8;
              type = LOCAL_GL_UNSIGNED_BYTE;
            }
            internalFormat = LOCAL_GL_RGBA;
            break;
        case SurfaceFormat::B8G8R8X8:
            // Treat BGRX surfaces as BGRA except for the surface
            // format used.
            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
              format = LOCAL_GL_BGRA;
              surfaceFormat = SurfaceFormat::R8G8B8X8;
              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
            } else {
              format = LOCAL_GL_RGBA;
              surfaceFormat = SurfaceFormat::B8G8R8X8;
              type = LOCAL_GL_UNSIGNED_BYTE;
            }
            internalFormat = LOCAL_GL_RGBA;
            break;
        case SurfaceFormat::R8G8B8A8:
            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
              // Upload our RGBA as BGRA, but store that the uploaded format is
              // BGRA. (sample from R to get B)
              format = LOCAL_GL_BGRA;
              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
              surfaceFormat = SurfaceFormat::B8G8R8A8;
            } else {
              format = LOCAL_GL_RGBA;
              type = LOCAL_GL_UNSIGNED_BYTE;
              surfaceFormat = SurfaceFormat::R8G8B8A8;
            }
            internalFormat = LOCAL_GL_RGBA;
            break;
        case SurfaceFormat::R8G8B8X8:
            // Treat RGBX surfaces as RGBA except for the surface
            // format used.
            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
              format = LOCAL_GL_BGRA;
              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
              surfaceFormat = SurfaceFormat::B8G8R8X8;
            } else {
              format = LOCAL_GL_RGBA;
              type = LOCAL_GL_UNSIGNED_BYTE;
              surfaceFormat = SurfaceFormat::R8G8B8X8;
            }
            internalFormat = LOCAL_GL_RGBA;
            break;
        case SurfaceFormat::R5G6B5_UINT16:
            internalFormat = format = LOCAL_GL_RGB;
            type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
            surfaceFormat = SurfaceFormat::R5G6B5_UINT16;
            break;
        case SurfaceFormat::A8:
            internalFormat = format = LOCAL_GL_LUMINANCE;
            type = LOCAL_GL_UNSIGNED_BYTE;
            // We don't have a specific luminance shader
            surfaceFormat = SurfaceFormat::A8;
            break;
        default:
            NS_ASSERTION(false, "Unhandled image surface format!");
    }

    if (aOutUploadSize) {
        *aOutUploadSize = 0;
    }

    if (aNeedInit || !CanUploadSubTextures(gl)) {
        // If the texture needs initialized, or we are unable to
        // upload sub textures, then initialize and upload the entire
        // texture.
        TexImage2DHelper(gl,
                         aTextureTarget,
                         0,
                         internalFormat,
                         aSize.width,
                         aSize.height,
                         aStride,
                         pixelSize,
                         0,
                         format,
                         type,
                         aData);

        if (aOutUploadSize && aNeedInit) {
            uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
            size_t numTexels = size_t(aSize.width) * size_t(aSize.height);
            *aOutUploadSize += texelSize * numTexels;
        }
    } else {
        // Upload each rect in the region to the texture
        for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) {
            const IntRect& rect = iter.Get();
            const unsigned char* rectData =
                aData + DataOffset(rect.TopLeft(), aStride, aFormat);

            TexSubImage2DHelper(gl,
                                aTextureTarget,
                                0,
                                rect.x,
                                rect.y,
                                rect.Width(),
                                rect.Height(),
                                aStride,
                                pixelSize,
                                format,
                                type,
                                rectData);
        }
    }

    return surfaceFormat;
}