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

Merge #1705 to CGD2D#1750

Merged
ms-jihua merged 2 commits into
microsoft:CGD2Dfrom
ms-jihua:enddraw_cgd2d_2
Jan 25, 2017
Merged

Merge #1705 to CGD2D#1750
ms-jihua merged 2 commits into
microsoft:CGD2Dfrom
ms-jihua:enddraw_cgd2d_2

Conversation

@ms-jihua

@ms-jihua ms-jihua commented Jan 20, 2017

Copy link
Copy Markdown
Contributor
  • Add PushBeginDraw/PopEndDraw pairs to UISegment, UIImage
    (not on develop since this likely would've actually hurt performance there)
  • Add Escape/Unescape pairs to CGContext areas where the target is changed

Fixes #1635


This change is Reviewable


deviceContext->BeginDraw();
EscapeBeginEndDrawStack();
deviceContext->SetTarget(commandList.Get());

@ms-jihua ms-jihua Jan 20, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DHowett-MSFT I think this is more correct placed here, right? #Resolved

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're correct. I recall Begin->Set->End being specified in one of the MSDN documents. #Resolved

@ms-jihua ms-jihua Jan 25, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I lied and it doesn't matter https://msdn.microsoft.com/en-us/library/windows/desktop/hh404533(v=vs.85).aspx leaving as-is for now, will look more deeply at this in the followup PR


In reply to: 97687941 [](ancestors = 97687941)

RETURN_IF_FAILED(deviceContext->CreateCommandList(&commandList));

deviceContext->BeginDraw();
EscapeBeginEndDrawStack();

@ms-jihua ms-jihua Jan 20, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the need to escape before changing targets, and because most functions in this file currently filter down to this function and thus change targets, #1705 has close-to-zero or probably negative impact on CGD2D as it currently is. Since we don't need a new command list each time this is called, I am going to add another iteration to this PR, tying the creation of new command lists to the stack. #WontFix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to do this in a separate PR instead


In reply to: 96997659 [](ancestors = 96997659)

@rajsesh rajsesh Jan 25, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please open a tracking issue to do this work. #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1810


In reply to: 97693686 [](ancestors = 97693686)

@aballway aballway left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval pending command list iteration

Comment thread Frameworks/UIKit/UISegment.mm Outdated
} else {
if (!_noDefaultImages) {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextRef ctx = ctx;

@aballway aballway Jan 20, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not needed #Resolved

microsoft#1705)

* CoreText Performance: Call ID2D1RenderTarget::BeginDraw()/EndDraw() fewer times

Fixes microsoft#1620

* - Added Begin/EndDraw pairs to a few more places
- Mitigated an issue with cairo where ID2D1RenderTarget would sometimes cache a before state during begin draw,
  and wipe out any changes cairo made, breaking APIs like CGContextFillRect.
- Changed implementation/naming of the 'escape the current begin/end draw stack' functions
Comment thread Frameworks/CoreGraphics/CGContext.mm Outdated

inline void EscapeBeginEndDrawStack() {
if ((_beginEndDrawDepth > 0) && ((_escapeBeginEndDrawDepth)++ == 0)) {
THROW_IF_FAILED(deviceContext->EndDraw());

@msft-Jeyaram msft-Jeyaram Jan 23, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THROW_IF_FAILED [](start = 12, length = 15)

who is catching the throws?
We standardized on FAIL_FAST #Resolved

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standardization we agreed on was to capture exceptions at the API boundary (which is usually the API entry point). Failing fast in the leaf nodes will lead to code that just arbitrarily quits with no possible recovery. Particularly when drawing to hardware device contexts, EndDraw() can fail, so we need to handle this with care. See #1194. #Pending

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you're actually advocating I do here, considering handling #1194 appears too large for the scope of this PR. As such, I'm going to take @msft-Jeyaram 's recommendation to follow the standard for now.


In reply to: 97468410 [](ancestors = 97468410)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recommendation is wrong, we agreed not to FAIL_FAST at arbitrary points in the CG code and instead throw. Any exceptions must be caught at the "C" entry point, where we decide either to return an error code/null or fail-fast if it is void.


In reply to: 97695158 [](ancestors = 97695158,97468410)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this is only one step away from the entry point.


In reply to: 97696710 [](ancestors = 97696710,97695158,97468410)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to approve this PR given that this is only one step away from the entry point.


In reply to: 97696881 [](ancestors = 97696881,97696710,97695158,97468410)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i actually already made the change anyway


In reply to: 97697849 [](ancestors = 97697849,97696881,97696710,97695158,97468410)

Comment thread Frameworks/CoreGraphics/CGContext.mm Outdated

inline void PopEndDraw() {
if (--(_beginEndDrawDepth) == 0) {
THROW_IF_FAILED(deviceContext->EndDraw());

@msft-Jeyaram msft-Jeyaram Jan 23, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here #Resolved

@msft-Jeyaram

Copy link
Copy Markdown

:shipit:

Comment thread Frameworks/include/CGContextInternal.h Outdated
// For scenarios where a Begin/EndDraw pair needs to be temporarily escaped, to be returned to at a later time
// Ie:
// - Switching render targets - Illegal to do so if currently in a Begin/EndDraw pair
// - Cairo - ID2D1RenderTarget is considered to 'own' the bitmap during Begin/EndDraw,

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can safely remove comment about cairo now. #Resolved

// TODO(DH)
bounds = self.bounds;
//bounds = CGContextGetClipBoundingBox(context);
// bounds = CGContextGetClipBoundingBox(context);

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove commented out line. Also, the whole thing could be CGRect bounds = self.bounds, or even just [self drawRect:self.bounds] since it is not being reused. #WontFix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DHowett-MSFT is taking care of this


In reply to: 97467495 [](ancestors = 97467495)

@rajsesh rajsesh Jan 25, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DHowett-MSFT, do we have an issue tracking this TODO? #Resolved

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1811 #Resolved

_CGGetPixelFormatProperties
_CGContextPushBeginDraw
_CGContextPopEndDraw
_CGContextEscapeBeginEndDrawStack

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These names are not ideal - they are vague (what does escaping the stack mean), and reveal the implementation detail (there is a stack). The later is not a big deal, but essentially what you doing here is ability to deal with a layer, so it might make sense to just call this _CGContextForceEndDraw() and _CGContextForceBeginDraw(), or _CGContextBeginLayerDraw/EndLayerDraw(). #WontFix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but they don't force an enddraw or a begindraw, nor are they exclusively tied to layers. they are 'enddraw if needed' and 'begindraw if needed', where 'needed' is kind of vague (if currently in the stack) and difficult to describe without mentioning the stack.

i agree that these names are bad, but the suggestions are less factually accurate, so i am won'tfixing this for now.


In reply to: 97468082 [](ancestors = 97468082)

@rajsesh rajsesh Jan 25, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think BeginDrawIfNeeded(), EndDrawIfNeeded() are more descriptive than EscapeStack. Won't fix is okay. #WontFix

centerRect.size = fontExtent;
// TODO(DH)
//EbrCenterTextInRectVertically(&centerRect, &fontExtent, _font);
// EbrCenterTextInRectVertically(&centerRect, &fontExtent, _font);

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code? also looks like there is a missing TODO issue, lets create it now. #WontFix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DHowett-MSFT is taking care of this


In reply to: 97468215 [](ancestors = 97468215)

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might not be necessary, but I'll add an issue to track "something about vertical text centering in UITextField"

This is more of a CT concern, but EbrCenterTextInRectVertically was part of CGContext for some unknown reason. #Resolved

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1812 #Resolved

Comment thread Frameworks/CoreGraphics/CGContext.mm Outdated

inline void EscapeBeginEndDrawStack() {
if ((_beginEndDrawDepth > 0) && ((_escapeBeginEndDrawDepth)++ == 0)) {
THROW_IF_FAILED(deviceContext->EndDraw());

@rajsesh rajsesh Jan 24, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standardization we agreed on was to capture exceptions at the API boundary (which is usually the API entry point). Failing fast in the leaf nodes will lead to code that just arbitrarily quits with no possible recovery. Particularly when drawing to hardware device contexts, EndDraw() can fail, so we need to handle this with care. See #1194. #Pending

@DHowett-MSFT DHowett-MSFT left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contingent upon @rajsesh-msft's requested changes, I think this is safe to go in.

We can improve the drawing stack later, but this will unblock our merge.


deviceContext->BeginDraw();
EscapeBeginEndDrawStack();
deviceContext->SetTarget(commandList.Get());

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're correct. I recall Begin->Set->End being specified in one of the MSDN documents. #Resolved

@ms-jihua

ms-jihua commented Jan 25, 2017

Copy link
Copy Markdown
Contributor Author

Then okay, let me just respond to the feedback on the table for now and get this actually performant later. #Resolved

Comment thread Frameworks/CoreGraphics/CGContext.mm Outdated

inline void PopEndDraw() {
if (--(_beginEndDrawDepth) == 0) {
FAIL_FAST_IF_FAILED(deviceContext->EndDraw());

@DHowett-MSFT DHowett-MSFT Jan 25, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The true recommendation was to have inner functions return HRESULT and FAIL_FAST or ignore the error gracefully at the C API boundary. #Pending

 - Add PushBeginDraw/PopEndDraw pairs to UISegment, UIImage
   (not on develop since this likely would've actually hurt performance there)
 - Add Escape/Unescape pairs to CGContext areas where the target is changed

Fixes microsoft#1635

cr feedback

cr feedback
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants