Skip to content

Commit

Permalink
Merge pull request #2120 from rajsesh-msft/release_1702.2
Browse files Browse the repository at this point in the history
Release 1702.2
  • Loading branch information
Raj Seshasankaran committed Mar 1, 2017
2 parents ee41314 + ff8784c commit 524a461
Show file tree
Hide file tree
Showing 26 changed files with 241 additions and 125 deletions.
18 changes: 12 additions & 6 deletions Frameworks/AutoLayout/AutoLayout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -473,23 +473,23 @@ - (BOOL)autoLayoutInvalidateContentSize {
if (CGSizeEqualToSize(layoutProperties->_intrinsicContentSize, newContentSize)) {
if (DEBUG_AUTO_LAYOUT_LIGHT) {
TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: Size {%f, %f} didn't change; no need to revalidate constraints; no need to re-layout %hs(0x%p).",
object_getClassName(self),
self,
newContentSize.width,
newContentSize.height);
newContentSize.height,
object_getClassName(self),
self);
}

// No more work left to be done; the size didn't actually change.
return NO;
} else {
if (DEBUG_AUTO_LAYOUT_LIGHT) {
TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: intrinsicContentSize changed from {%f, %f} to {%f, %f}; need to revalidate constraints and re-layout %hs(0x%p).",
object_getClassName(self),
self,
newContentSize.width,
newContentSize.height,
layoutProperties->_intrinsicContentSize.width,
layoutProperties->_intrinsicContentSize.height);
layoutProperties->_intrinsicContentSize.height,
object_getClassName(self),
self);
}

// Store the new intrinsicContentSize
Expand Down Expand Up @@ -611,6 +611,12 @@ - (UIView*)autolayoutRoot {
- (void)autoLayoutUpdateConstraints {
AutoLayoutProperties* layoutProperties = self._autoLayoutProperties;

if (DEBUG_AUTO_LAYOUT_LIGHT) {
TraceVerbose(TAG, L"autoLayoutUpdateConstraints: %hs(0x%p).",
object_getClassName(self),
self);
}

if (![layoutProperties->_associatedConstraints count]) {
return;
}
Expand Down
13 changes: 13 additions & 0 deletions Frameworks/CoreGraphics/CGContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2935,7 +2935,20 @@ CGContextRef CGBitmapContextCreateWithData(void* data,
RETURN_NULL_IF(!height);
RETURN_NULL_IF(!colorSpace);

size_t imputedBitsPerPixel = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo);
size_t bitsPerPixel = ((bytesPerRow / width) << 3);
size_t estimatedBytesPerRow = (imputedBitsPerPixel >> 3) * width;

if (data && estimatedBytesPerRow > bytesPerRow) {
TraceError(TAG, L"Invalid data stride: a %ux%u %ubpp context requires at least a %u-byte stride (requested: %u bytes/row).", width, height, imputedBitsPerPixel, estimatedBytesPerRow, bytesPerRow);
return nullptr;
}

if (!bytesPerRow) { // When data is not provided, we are allowed to use our estimates.
bitsPerPixel = imputedBitsPerPixel;
bytesPerRow = estimatedBytesPerRow;
}

WICPixelFormatGUID requestedPixelFormat;
RETURN_NULL_IF_FAILED(
_CGImageGetWICPixelFormatFromImageProperties(bitsPerComponent, bitsPerPixel, colorSpace, bitmapInfo, &requestedPixelFormat));
Expand Down
73 changes: 52 additions & 21 deletions Frameworks/CoreGraphics/CGImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@

static const wchar_t* TAG = L"CGImage";

// TODO #1124: remove old code
#pragma region OLD_CODE
// This is used by XamlCompositor to flush the DisplayTexture cache.
// TODO GH#2098 look at where we're using the image cache and what we can do to avoid it.
static std::vector<CGImageDestructionListener> _imageDestructionListeners;
COREGRAPHICS_EXPORT void CGImageAddDestructionListener(CGImageDestructionListener listener) {
_imageDestructionListeners.push_back(listener);
}

#pragma endregion OLD_CODE

#pragma region CGImageImplementation

struct __CGImageImpl {
Expand Down Expand Up @@ -225,6 +223,12 @@ inline WICPixelFormatGUID PixelFormat() const {
_impl.renderingIntent = intent;
return *this;
}

~__CGImage() {
for (auto listener : _imageDestructionListeners) {
listener(this);
}
}
};

#pragma endregion CGImageImplementation
Expand Down Expand Up @@ -362,7 +366,9 @@ CGDataProviderRef CGImageGetDataProvider(CGImageRef img) {
RETURN_NULL_IF_FAILED(img->ImageSource()->CopyPixels(nullptr, stride, size, buffer.get()));

CGDataProviderRef dataProvider =
CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) { IwFree(const_cast<void*>(data)); });
CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) {
IwFree(const_cast<void*>(data));
});
CFAutorelease(dataProvider);
return dataProvider;
}
Expand Down Expand Up @@ -646,6 +652,12 @@ CGImageRef _CGImageCreateCopyWithPixelFormat(CGImageRef image, WICPixelFormatGUI
return imageRef;
}

CGImageRef _CGImageCreateFromDataProvider(CGDataProviderRef provider) {
RETURN_NULL_IF(!provider);
unsigned char* dataBytes = static_cast<unsigned char*>(const_cast<void*>(_CGDataProviderGetData(provider)));
return _CGImageGetImageFromData(dataBytes, _CGDataProviderGetSize(provider));
}

CGImageRef _CGImageGetImageFromData(void* data, int length) {
return _CGImageLoadImageWithWICDecoder(GUID_NULL, data, length);
}
Expand Down Expand Up @@ -710,6 +722,36 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int
return nil;
}

size_t _CGImageImputeBitsPerPixelFromFormat(CGColorSpaceRef colorSpace, size_t bitsPerComponent, CGBitmapInfo bitmapInfo) {
unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;
unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask;

// Try byte order first: The user can specify 32 or 16 directly.
switch (byteOrder) {
case kCGBitmapByteOrder32Little:
case kCGBitmapByteOrder32Big:
return 32;
case kCGBitmapByteOrder16Little:
case kCGBitmapByteOrder16Big:
return 16;
}

// Otherwise, try to figure out how many components there are.
size_t nComponents = CGColorSpaceGetNumberOfComponents(colorSpace);
switch (alphaInfo) {
case kCGImageAlphaNoneSkipFirst:
case kCGImageAlphaPremultipliedFirst:
case kCGImageAlphaFirst:
case kCGImageAlphaNoneSkipLast:
case kCGImageAlphaPremultipliedLast:
case kCGImageAlphaLast:
nComponents += 1;
break;
}

return (bitsPerComponent * nComponents);
}

// CG packed format key
// |Color |bits/px|CGBitmapInfo |
// |-------|-------|---------------|
Expand All @@ -719,7 +761,6 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int

HRESULT _CGImageGetWICPixelFormatFromImageProperties(
unsigned int bitsPerComponent, unsigned int bitsPerPixel, CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo, GUID* pixelFormat) {

// clang-format off
static std::map<uint32_t, WICPixelFormatGUID> s_CGWICFormatMap{
{ CG_FORMAT_KEY(kCGColorSpaceModelRGB , 24, kCGBitmapByteOrderDefault, kCGImageAlphaNone), GUID_WICPixelFormat24bppRGB },
Expand Down Expand Up @@ -766,23 +807,13 @@ HRESULT _CGImageGetWICPixelFormatFromImageProperties(

RETURN_HR_IF(E_POINTER, !pixelFormat);

CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);

unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;
unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask;
unsigned int formatImputedBpp = 0;
switch (byteOrder) {
case kCGBitmapByteOrder32Little:
case kCGBitmapByteOrder32Big:
formatImputedBpp = 32;
break;
case kCGBitmapByteOrder16Little:
case kCGBitmapByteOrder16Big:
formatImputedBpp = 16;
break;
size_t formatImputedBpp = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo);
if (bitsPerPixel == 0) {
bitsPerPixel = formatImputedBpp;
}

if (formatImputedBpp == 0 || formatImputedBpp == bitsPerPixel) {
if (formatImputedBpp == bitsPerPixel) {
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
auto found = s_CGWICFormatMap.find(CG_FORMAT_KEY(colorSpaceModel, bitsPerPixel, bitmapInfo, 0));
if (found != s_CGWICFormatMap.end()) {
*pixelFormat = found->second;
Expand Down
11 changes: 7 additions & 4 deletions Frameworks/GLKit/GLKTexture.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
Expand All @@ -25,6 +25,7 @@
#import <GLKit/GLKitExport.h>
#import <GLKit/GLKTexture.h>
#import "NSLogging.h"
#import "CGImageInternal.h"

static const wchar_t* TAG = L"GLKTexture";

Expand Down Expand Up @@ -277,7 +278,7 @@ @implementation GLKTextureLoader {
*/
+ (GLKTextureInfo*)textureWithContentsOfFile:(NSString*)fname options:(NSDictionary*)opts error:(NSError**)err {
CGDataProviderRef provider = CGDataProviderCreateWithFilename([fname UTF8String]);
CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);
CGImageRef img = _CGImageCreateFromDataProvider(provider);

GLKTextureInfo* res = [self textureWithCGImage:img options:opts error:err];

Expand Down Expand Up @@ -395,7 +396,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFile:(NSString*)fname options:(NSDiction
if (!provider) {
return nil;
}
CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);

CGImageRef img = _CGImageCreateFromDataProvider(provider);
if (!img) {
CGDataProviderRelease(provider);
return nil;
Expand Down Expand Up @@ -541,7 +543,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFiles:(NSArray*)fnames options:(NSDictio
curSide++;
continue;
}
CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);

CGImageRef img = _CGImageCreateFromDataProvider(provider);
if (!img) {
CGDataProviderRelease(provider);
NSTraceWarning(TAG, @"Unable to create image from cube side texture %@", fn);
Expand Down
22 changes: 14 additions & 8 deletions Frameworks/QuartzCore/CALayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -427,14 +427,20 @@ - (void)renderInContext:(CGContextRef)ctx {
[priv->delegate drawLayer:self inContext:ctx];
}
} else {
CGRect rect;

rect.origin.x = 0;
rect.origin.y = priv->bounds.size.height * priv->contentsScale;
rect.size.width = priv->bounds.size.width * priv->contentsScale;
rect.size.height = -priv->bounds.size.height * priv->contentsScale;

_CGContextDrawImageRect(ctx, priv->contents, rect, destRect);
// If the layer has cached contents, blit them directly.

// Since the layer was rendered in Quartz referential (ULO) AND the current context
// is assumed to be Quartz referential (ULO), BUT the layer's cached contents
// were captured in a CGImage (CGImage referential, LLO), we have to flip
// the context again before we render it.

// |1 0 0| is the transformation matrix for flipping a rect anchored at 0,0 about its Y midpoint.
// |0 -1 0|
// |0 h 1|
CGContextSaveGState(ctx);
CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, destRect.size.height));
CGContextDrawImage(ctx, destRect, priv->contents);
CGContextRestoreGState(ctx);
}

// Draw sublayers
Expand Down
Loading

0 comments on commit 524a461

Please sign in to comment.