Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 524a461

Browse files
author
Raj Seshasankaran
authored
Merge pull request #2120 from rajsesh-msft/release_1702.2
Release 1702.2
2 parents ee41314 + ff8784c commit 524a461

File tree

26 files changed

+241
-125
lines changed

26 files changed

+241
-125
lines changed

Frameworks/AutoLayout/AutoLayout.mm

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,23 +473,23 @@ - (BOOL)autoLayoutInvalidateContentSize {
473473
if (CGSizeEqualToSize(layoutProperties->_intrinsicContentSize, newContentSize)) {
474474
if (DEBUG_AUTO_LAYOUT_LIGHT) {
475475
TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: Size {%f, %f} didn't change; no need to revalidate constraints; no need to re-layout %hs(0x%p).",
476-
object_getClassName(self),
477-
self,
478476
newContentSize.width,
479-
newContentSize.height);
477+
newContentSize.height,
478+
object_getClassName(self),
479+
self);
480480
}
481481

482482
// No more work left to be done; the size didn't actually change.
483483
return NO;
484484
} else {
485485
if (DEBUG_AUTO_LAYOUT_LIGHT) {
486486
TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: intrinsicContentSize changed from {%f, %f} to {%f, %f}; need to revalidate constraints and re-layout %hs(0x%p).",
487-
object_getClassName(self),
488-
self,
489487
newContentSize.width,
490488
newContentSize.height,
491489
layoutProperties->_intrinsicContentSize.width,
492-
layoutProperties->_intrinsicContentSize.height);
490+
layoutProperties->_intrinsicContentSize.height,
491+
object_getClassName(self),
492+
self);
493493
}
494494

495495
// Store the new intrinsicContentSize
@@ -611,6 +611,12 @@ - (UIView*)autolayoutRoot {
611611
- (void)autoLayoutUpdateConstraints {
612612
AutoLayoutProperties* layoutProperties = self._autoLayoutProperties;
613613

614+
if (DEBUG_AUTO_LAYOUT_LIGHT) {
615+
TraceVerbose(TAG, L"autoLayoutUpdateConstraints: %hs(0x%p).",
616+
object_getClassName(self),
617+
self);
618+
}
619+
614620
if (![layoutProperties->_associatedConstraints count]) {
615621
return;
616622
}

Frameworks/CoreGraphics/CGContext.mm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,7 +2935,20 @@ CGContextRef CGBitmapContextCreateWithData(void* data,
29352935
RETURN_NULL_IF(!height);
29362936
RETURN_NULL_IF(!colorSpace);
29372937

2938+
size_t imputedBitsPerPixel = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo);
29382939
size_t bitsPerPixel = ((bytesPerRow / width) << 3);
2940+
size_t estimatedBytesPerRow = (imputedBitsPerPixel >> 3) * width;
2941+
2942+
if (data && estimatedBytesPerRow > bytesPerRow) {
2943+
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);
2944+
return nullptr;
2945+
}
2946+
2947+
if (!bytesPerRow) { // When data is not provided, we are allowed to use our estimates.
2948+
bitsPerPixel = imputedBitsPerPixel;
2949+
bytesPerRow = estimatedBytesPerRow;
2950+
}
2951+
29392952
WICPixelFormatGUID requestedPixelFormat;
29402953
RETURN_NULL_IF_FAILED(
29412954
_CGImageGetWICPixelFormatFromImageProperties(bitsPerComponent, bitsPerPixel, colorSpace, bitmapInfo, &requestedPixelFormat));

Frameworks/CoreGraphics/CGImage.mm

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,13 @@
3939

4040
static const wchar_t* TAG = L"CGImage";
4141

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

49-
#pragma endregion OLD_CODE
50-
5149
#pragma region CGImageImplementation
5250

5351
struct __CGImageImpl {
@@ -225,6 +223,12 @@ inline WICPixelFormatGUID PixelFormat() const {
225223
_impl.renderingIntent = intent;
226224
return *this;
227225
}
226+
227+
~__CGImage() {
228+
for (auto listener : _imageDestructionListeners) {
229+
listener(this);
230+
}
231+
}
228232
};
229233

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

364368
CGDataProviderRef dataProvider =
365-
CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) { IwFree(const_cast<void*>(data)); });
369+
CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) {
370+
IwFree(const_cast<void*>(data));
371+
});
366372
CFAutorelease(dataProvider);
367373
return dataProvider;
368374
}
@@ -646,6 +652,12 @@ CGImageRef _CGImageCreateCopyWithPixelFormat(CGImageRef image, WICPixelFormatGUI
646652
return imageRef;
647653
}
648654

655+
CGImageRef _CGImageCreateFromDataProvider(CGDataProviderRef provider) {
656+
RETURN_NULL_IF(!provider);
657+
unsigned char* dataBytes = static_cast<unsigned char*>(const_cast<void*>(_CGDataProviderGetData(provider)));
658+
return _CGImageGetImageFromData(dataBytes, _CGDataProviderGetSize(provider));
659+
}
660+
649661
CGImageRef _CGImageGetImageFromData(void* data, int length) {
650662
return _CGImageLoadImageWithWICDecoder(GUID_NULL, data, length);
651663
}
@@ -710,6 +722,36 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int
710722
return nil;
711723
}
712724

725+
size_t _CGImageImputeBitsPerPixelFromFormat(CGColorSpaceRef colorSpace, size_t bitsPerComponent, CGBitmapInfo bitmapInfo) {
726+
unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;
727+
unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask;
728+
729+
// Try byte order first: The user can specify 32 or 16 directly.
730+
switch (byteOrder) {
731+
case kCGBitmapByteOrder32Little:
732+
case kCGBitmapByteOrder32Big:
733+
return 32;
734+
case kCGBitmapByteOrder16Little:
735+
case kCGBitmapByteOrder16Big:
736+
return 16;
737+
}
738+
739+
// Otherwise, try to figure out how many components there are.
740+
size_t nComponents = CGColorSpaceGetNumberOfComponents(colorSpace);
741+
switch (alphaInfo) {
742+
case kCGImageAlphaNoneSkipFirst:
743+
case kCGImageAlphaPremultipliedFirst:
744+
case kCGImageAlphaFirst:
745+
case kCGImageAlphaNoneSkipLast:
746+
case kCGImageAlphaPremultipliedLast:
747+
case kCGImageAlphaLast:
748+
nComponents += 1;
749+
break;
750+
}
751+
752+
return (bitsPerComponent * nComponents);
753+
}
754+
713755
// CG packed format key
714756
// |Color |bits/px|CGBitmapInfo |
715757
// |-------|-------|---------------|
@@ -719,7 +761,6 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int
719761

720762
HRESULT _CGImageGetWICPixelFormatFromImageProperties(
721763
unsigned int bitsPerComponent, unsigned int bitsPerPixel, CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo, GUID* pixelFormat) {
722-
723764
// clang-format off
724765
static std::map<uint32_t, WICPixelFormatGUID> s_CGWICFormatMap{
725766
{ CG_FORMAT_KEY(kCGColorSpaceModelRGB , 24, kCGBitmapByteOrderDefault, kCGImageAlphaNone), GUID_WICPixelFormat24bppRGB },
@@ -766,23 +807,13 @@ HRESULT _CGImageGetWICPixelFormatFromImageProperties(
766807

767808
RETURN_HR_IF(E_POINTER, !pixelFormat);
768809

769-
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
770-
771-
unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;
772-
unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask;
773-
unsigned int formatImputedBpp = 0;
774-
switch (byteOrder) {
775-
case kCGBitmapByteOrder32Little:
776-
case kCGBitmapByteOrder32Big:
777-
formatImputedBpp = 32;
778-
break;
779-
case kCGBitmapByteOrder16Little:
780-
case kCGBitmapByteOrder16Big:
781-
formatImputedBpp = 16;
782-
break;
810+
size_t formatImputedBpp = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo);
811+
if (bitsPerPixel == 0) {
812+
bitsPerPixel = formatImputedBpp;
783813
}
784814

785-
if (formatImputedBpp == 0 || formatImputedBpp == bitsPerPixel) {
815+
if (formatImputedBpp == bitsPerPixel) {
816+
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
786817
auto found = s_CGWICFormatMap.find(CG_FORMAT_KEY(colorSpaceModel, bitsPerPixel, bitmapInfo, 0));
787818
if (found != s_CGWICFormatMap.end()) {
788819
*pixelFormat = found->second;

Frameworks/GLKit/GLKTexture.mm

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//******************************************************************************
22
//
3-
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
3+
// Copyright (c) Microsoft. All rights reserved.
44
//
55
// This code is licensed under the MIT License (MIT).
66
//
@@ -25,6 +25,7 @@
2525
#import <GLKit/GLKitExport.h>
2626
#import <GLKit/GLKTexture.h>
2727
#import "NSLogging.h"
28+
#import "CGImageInternal.h"
2829

2930
static const wchar_t* TAG = L"GLKTexture";
3031

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

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

@@ -395,7 +396,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFile:(NSString*)fname options:(NSDiction
395396
if (!provider) {
396397
return nil;
397398
}
398-
CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);
399+
400+
CGImageRef img = _CGImageCreateFromDataProvider(provider);
399401
if (!img) {
400402
CGDataProviderRelease(provider);
401403
return nil;
@@ -541,7 +543,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFiles:(NSArray*)fnames options:(NSDictio
541543
curSide++;
542544
continue;
543545
}
544-
CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);
546+
547+
CGImageRef img = _CGImageCreateFromDataProvider(provider);
545548
if (!img) {
546549
CGDataProviderRelease(provider);
547550
NSTraceWarning(TAG, @"Unable to create image from cube side texture %@", fn);

Frameworks/QuartzCore/CALayer.mm

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -427,14 +427,20 @@ - (void)renderInContext:(CGContextRef)ctx {
427427
[priv->delegate drawLayer:self inContext:ctx];
428428
}
429429
} else {
430-
CGRect rect;
431-
432-
rect.origin.x = 0;
433-
rect.origin.y = priv->bounds.size.height * priv->contentsScale;
434-
rect.size.width = priv->bounds.size.width * priv->contentsScale;
435-
rect.size.height = -priv->bounds.size.height * priv->contentsScale;
436-
437-
_CGContextDrawImageRect(ctx, priv->contents, rect, destRect);
430+
// If the layer has cached contents, blit them directly.
431+
432+
// Since the layer was rendered in Quartz referential (ULO) AND the current context
433+
// is assumed to be Quartz referential (ULO), BUT the layer's cached contents
434+
// were captured in a CGImage (CGImage referential, LLO), we have to flip
435+
// the context again before we render it.
436+
437+
// |1 0 0| is the transformation matrix for flipping a rect anchored at 0,0 about its Y midpoint.
438+
// |0 -1 0|
439+
// |0 h 1|
440+
CGContextSaveGState(ctx);
441+
CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, destRect.size.height));
442+
CGContextDrawImage(ctx, destRect, priv->contents);
443+
CGContextRestoreGState(ctx);
438444
}
439445

440446
// Draw sublayers

0 commit comments

Comments
 (0)